Skip to content

Commit 471d8a6

Browse files
committed
add test case and fix bug
1 parent bd1bfd3 commit 471d8a6

File tree

5 files changed

+56
-12
lines changed

5 files changed

+56
-12
lines changed

demeter/uniswap/core.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from ._typing import UniV3Pool, Position, UniV3PoolStatus, PositionInfo
66
from .helper import base_unit_price_to_tick, from_atomic_unit
77
from .liquitidy_math import get_amounts, get_liquidity
8+
from .. import DECIMAL_1
89

910

1011
class V3CoreLib(object):
@@ -127,8 +128,7 @@ def update_fee(last_tick: int, pool: UniV3Pool, pos: PositionInfo, position: Pos
127128
:return: None
128129
"""
129130

130-
def calc_amounts(weight):
131-
weight = Decimal(weight)
131+
def calc_amounts(weight: Decimal):
132132
share = Decimal(position.liquidity) / Decimal(state.currentLiquidity)
133133
position.pending_amount0 += (
134134
weight * from_atomic_unit(state.inAmount0, pool.token0.decimal) * share * pool.fee_rate
@@ -148,12 +148,12 @@ def in_range(tick):
148148
now_in_range = in_range(state.closeTick)
149149
last_in_range = in_range(last_tick)
150150

151-
if now_in_range == last_in_range: # all in range, or below lower or above upper
152-
if now_in_range == 0: # all in range
153-
calc_amounts(1)
151+
if now_in_range == last_in_range: # all in range, or below lower or above upper
152+
if now_in_range == 0: # all in range
153+
calc_amounts(DECIMAL_1)
154154
else:
155155
return
156-
else: # price cross range, even from above upper to below lower
156+
else: # price cross range, even from above upper to below lower
157157
# calculate percentage of in range
158158
# use in_range / price_moved
159159
range_list = [pos.lower_tick, pos.upper_tick, last_tick, state.closeTick]
@@ -162,10 +162,10 @@ def in_range(tick):
162162
return
163163
price_delta = np.abs(last_tick - state.closeTick)
164164
in_range_delta = range_list[2] - range_list[1]
165-
weight = in_range_delta / price_delta
166-
if weight > 1: # alert for error
165+
weight_decimal = Decimal(in_range_delta) / Decimal(price_delta)
166+
if weight_decimal > 1: # alert for error
167167
raise RuntimeError("weight must <=1")
168-
calc_amounts(in_range_delta / price_delta)
168+
calc_amounts(weight_decimal)
169169

170170
@staticmethod
171171
def update_fee_old(last_tick: int, pool: UniV3Pool, pos: PositionInfo, position: Position, state: UniV3PoolStatus):

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
project = 'Demeter'
1616
copyright = '2024, zelos research'
1717
author = 'zelos research'
18-
release = '0.7.5'
18+
release = '0.7.6'
1919

2020
# -- General configuration ---------------------------------------------------
2121
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

release_note.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Ver 0.7.6
2+
3+
* For uniswap v3, when price is in and out of price range in this minute, fee will be calculated more accurately
4+
15
# Ver 0.7.5
26

37
* Fix bugs in aave

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
setup(
99
name="zelos-demeter",
10-
version="0.7.5",
10+
version="0.7.6",
1111
packages=find_packages(exclude=["tests", "tests.*", "samples", "samples.*"]),
1212
url="https://zelos-demeter.readthedocs.io",
1313
license="MIT",

tests/uni_lp_core_test.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import math
22
import unittest
3+
from bdb import effective
34
from decimal import Decimal
45

56
from demeter import TokenInfo
6-
from demeter.uniswap import V3CoreLib, UniV3Pool
7+
from demeter.uniswap import V3CoreLib, UniV3Pool, UniV3PoolStatus, PositionInfo, Position
78
from demeter.uniswap.helper import (
89
tick_to_sqrt_price_x96,
910
get_swap_value,
@@ -234,3 +235,42 @@ def test_nearly_full(self):
234235
math.isclose(actual_from + actual_to + m * fee_rate, to_invest_f + to_invest_t, abs_tol=0.000001)
235236
)
236237
self.assertGreaterEqual(from_val + to_val, actual_from + actual_to + m * fee_rate)
238+
239+
def test_fee(self):
240+
token0 = TokenInfo("eth", 0)
241+
token1 = TokenInfo("usd", 0)
242+
pool = UniV3Pool(token0, token1, 1, token1)
243+
state = UniV3PoolStatus(currentLiquidity=10000, inAmount0=10000, inAmount1=10000, price=Decimal(1))
244+
pos: PositionInfo = PositionInfo(5, 10)
245+
# =======In range==============
246+
position: Position = Position(Decimal(0), Decimal(0), 500, None, None)
247+
last_tick = 6
248+
state.closeTick = 7
249+
V3CoreLib.update_fee(last_tick, pool, pos, position, state)
250+
self.assertEqual(position.pending_amount0, Decimal("5"))
251+
# =======out range=============
252+
position: Position = Position(Decimal(0), Decimal(0), 500, None, None)
253+
last_tick = 12
254+
state.closeTick = 14
255+
V3CoreLib.update_fee(last_tick, pool, pos, position, state)
256+
self.assertEqual(position.pending_amount0, Decimal("0"))
257+
# =======out then in, share should be 1=============
258+
position: Position = Position(Decimal(0), Decimal(0), 500, None, None)
259+
last_tick = 1
260+
state.closeTick = 6
261+
V3CoreLib.update_fee(last_tick, pool, pos, position, state)
262+
self.assertEqual(position.pending_amount0, Decimal(1))
263+
264+
# =======in then out, share should be 2=============
265+
position: Position = Position(Decimal(0), Decimal(0), 500, None, None)
266+
last_tick = 8
267+
state.closeTick = 13
268+
V3CoreLib.update_fee(last_tick, pool, pos, position, state)
269+
self.assertEqual(position.pending_amount0, Decimal(2))
270+
271+
# =======from upper out to lower out=============
272+
position: Position = Position(Decimal(0), Decimal(0), 500, None, None)
273+
last_tick = 3
274+
state.closeTick = 13
275+
V3CoreLib.update_fee(last_tick, pool, pos, position, state)
276+
self.assertEqual(position.pending_amount0, Decimal("2.5"))

0 commit comments

Comments
 (0)