Skip to content

Commit

Permalink
test initializer initialize pool sqrt price oracle less/greater than …
Browse files Browse the repository at this point in the history
…price, price at extremes
  • Loading branch information
0xcivita committed Jan 26, 2024
1 parent bd0fe22 commit aeca903
Showing 1 changed file with 264 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
from ape import reverts

from utils.constants import MIN_SQRT_RATIO, MAX_SQRT_RATIO, MINIMUM_LIQUIDITY
from utils.utils import calc_amounts_from_liquidity_sqrt_price_x96


def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96(
def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96_when_greater_than_oracle(
initializer,
mock_univ3_pool,
pool,
Expand All @@ -22,7 +23,8 @@ def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96(

slot0 = mock_univ3_pool.slot0()
state = pool.state()
assert slot0.sqrtPriceX96 != state.sqrtPriceX96

assert slot0.sqrtPriceX96 < state.sqrtPriceX96
assert state.liquidity == MINIMUM_LIQUIDITY**2

amount_in_max = 2**256 - 1
Expand All @@ -48,7 +50,75 @@ def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96(
initializer.initializePoolSqrtPriceX96(params, sender=sender)

result = pool.state()
assert pytest.approx(result.sqrtPriceX96, rel=1e-4) == slot0.sqrtPriceX96
assert pytest.approx(result.sqrtPriceX96, rel=2e-4) == slot0.sqrtPriceX96


def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96_when_less_than_oracle(
initializer,
mock_univ3_pool,
pool,
callee,
sender,
alice,
token0,
token1,
chain,
swap_math_lib,
):
# add minimum amount of liquidity
callee.mint(pool.address, sender.address, MINIMUM_LIQUIDITY**2, sender=sender)

slot0 = mock_univ3_pool.slot0()
state = pool.state()

assert slot0.sqrtPriceX96 < state.sqrtPriceX96
assert state.liquidity == MINIMUM_LIQUIDITY**2

amount_in_max = 2**256 - 1
amount_out_min = 0
zero_for_one = slot0.sqrtPriceX96 < state.sqrtPriceX96
sqrt_price_limit_x96 = MIN_SQRT_RATIO + 1 if zero_for_one else MAX_SQRT_RATIO - 1
deadline = chain.pending_timestamp + 3600

# move price on marginal pool to below uni price for test of less than sqrt price
sqrt_price_x96_next = (slot0.sqrtPriceX96**2) // state.sqrtPriceX96
assert sqrt_price_x96_next < slot0.sqrtPriceX96
params = (
pool.token0(),
pool.token1(),
pool.maintenance(),
pool.oracle(),
alice.address,
sqrt_price_x96_next,
amount_in_max,
amount_out_min,
sqrt_price_limit_x96,
deadline,
)
initializer.initializePoolSqrtPriceX96(params, sender=sender)

state = pool.state()
assert pytest.approx(state.sqrtPriceX96, rel=2e-4) == sqrt_price_x96_next

assert slot0.sqrtPriceX96 > state.sqrtPriceX96
zero_for_one = slot0.sqrtPriceX96 < state.sqrtPriceX96
sqrt_price_limit_x96 = MIN_SQRT_RATIO + 1 if zero_for_one else MAX_SQRT_RATIO - 1
params = (
pool.token0(),
pool.token1(),
pool.maintenance(),
pool.oracle(),
alice.address,
slot0.sqrtPriceX96,
amount_in_max,
amount_out_min,
sqrt_price_limit_x96,
deadline,
)
initializer.initializePoolSqrtPriceX96(params, sender=sender)

result = pool.state()
assert pytest.approx(result.sqrtPriceX96, rel=2e-4) == slot0.sqrtPriceX96


def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96_when_amount_in_max_zero(
Expand All @@ -68,7 +138,7 @@ def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96_when

slot0 = mock_univ3_pool.slot0()
state = pool.state()
assert slot0.sqrtPriceX96 != state.sqrtPriceX96
assert slot0.sqrtPriceX96 < state.sqrtPriceX96
assert state.liquidity == MINIMUM_LIQUIDITY**2

amount_in_max = 0
Expand All @@ -94,7 +164,195 @@ def test_initializer_initialize_pool_sqrt_price_x96__sets_to_sqrt_price_x96_when
initializer.initializePoolSqrtPriceX96(params, sender=sender)

result = pool.state()
assert pytest.approx(result.sqrtPriceX96, rel=1e-4) == slot0.sqrtPriceX96
assert pytest.approx(result.sqrtPriceX96, rel=2e-4) == slot0.sqrtPriceX96


def test_initializer_initialize_pool_sqrt_price_x96__set_to_min_sqrt_ratio_swaps_back(
initializer,
mock_univ3_pool,
pool,
callee,
sender,
alice,
token0,
token1,
chain,
swap_math_lib,
sqrt_price_math_lib,
):
# add minimum amount of liquidity
callee.mint(pool.address, sender.address, MINIMUM_LIQUIDITY**2, sender=sender)

slot0 = mock_univ3_pool.slot0()
state = pool.state()

amount_in_max = 0
amount_out_min = 0
sqrt_price_limit_x96 = 0
deadline = chain.pending_timestamp + 3600

(reserve0, reserve1) = calc_amounts_from_liquidity_sqrt_price_x96(
state.liquidity, state.sqrtPriceX96
)

zero_for_one = True
sqrt_price_x96_next = sqrt_price_math_lib.sqrtPriceX96NextSwap(
state.liquidity,
state.sqrtPriceX96,
zero_for_one,
-reserve0 + 1 if not zero_for_one else -reserve1 + 1,
)

# mint large amounts
(amount0_delta, amount1_delta) = swap_math_lib.swapAmounts(
state.liquidity, state.sqrtPriceX96, sqrt_price_x96_next
)

if amount0_delta > 0:
token0.mint(sender.address, amount0_delta * 10, sender=sender)
elif amount1_delta > 0:
token1.mint(sender.address, amount1_delta * 10, sender=sender)

# move price on marginal pool to uni price
params = (
pool.token0(),
pool.token1(),
pool.maintenance(),
pool.oracle(),
alice.address,
sqrt_price_x96_next,
amount_in_max,
amount_out_min,
sqrt_price_limit_x96,
deadline,
)
initializer.initializePoolSqrtPriceX96(params, sender=sender)

state = pool.state()
assert pytest.approx(state.sqrtPriceX96, rel=2e-1) == sqrt_price_x96_next

# mint again to do next swap
(amount0_delta, amount1_delta) = swap_math_lib.swapAmounts(
state.liquidity, state.sqrtPriceX96, slot0.sqrtPriceX96
)

# mint large amounts
if amount0_delta > 0:
token0.mint(sender.address, amount0_delta * 10, sender=sender)
elif amount1_delta > 0:
token1.mint(sender.address, amount1_delta * 10, sender=sender)

# move price back to uni price
params = (
pool.token0(),
pool.token1(),
pool.maintenance(),
pool.oracle(),
alice.address,
slot0.sqrtPriceX96,
amount_in_max,
amount_out_min,
sqrt_price_limit_x96,
deadline,
)
initializer.initializePoolSqrtPriceX96(params, sender=sender)

result = pool.state()
assert pytest.approx(result.sqrtPriceX96, rel=1e-3) == slot0.sqrtPriceX96


def test_initializer_initialize_pool_sqrt_price_x96__set_to_max_sqrt_ratio_swaps_back(
initializer,
mock_univ3_pool,
pool,
callee,
sender,
alice,
token0,
token1,
chain,
swap_math_lib,
sqrt_price_math_lib,
):
# add minimum amount of liquidity
callee.mint(pool.address, sender.address, MINIMUM_LIQUIDITY**2, sender=sender)

slot0 = mock_univ3_pool.slot0()
state = pool.state()

amount_in_max = 0
amount_out_min = 0
sqrt_price_limit_x96 = 0
deadline = chain.pending_timestamp + 3600

(reserve0, reserve1) = calc_amounts_from_liquidity_sqrt_price_x96(
state.liquidity, state.sqrtPriceX96
)

zero_for_one = False
sqrt_price_x96_next = sqrt_price_math_lib.sqrtPriceX96NextSwap(
state.liquidity,
state.sqrtPriceX96,
zero_for_one,
-reserve0 + 1 if not zero_for_one else -reserve1 + 1,
)

# mint large amounts
(amount0_delta, amount1_delta) = swap_math_lib.swapAmounts(
state.liquidity, state.sqrtPriceX96, sqrt_price_x96_next
)

if amount0_delta > 0:
token0.mint(sender.address, amount0_delta * 10, sender=sender)
elif amount1_delta > 0:
token1.mint(sender.address, amount1_delta * 10, sender=sender)

# move price on marginal pool to uni price
params = (
pool.token0(),
pool.token1(),
pool.maintenance(),
pool.oracle(),
alice.address,
sqrt_price_x96_next,
amount_in_max,
amount_out_min,
sqrt_price_limit_x96,
deadline,
)
initializer.initializePoolSqrtPriceX96(params, sender=sender)

state = pool.state()
assert pytest.approx(state.sqrtPriceX96, rel=2e-1) == sqrt_price_x96_next

# mint again to do next swap
(amount0_delta, amount1_delta) = swap_math_lib.swapAmounts(
state.liquidity, state.sqrtPriceX96, slot0.sqrtPriceX96
)

# mint large amounts
if amount0_delta > 0:
token0.mint(sender.address, amount0_delta * 10, sender=sender)
elif amount1_delta > 0:
token1.mint(sender.address, amount1_delta * 10, sender=sender)

# move price back to uni price
params = (
pool.token0(),
pool.token1(),
pool.maintenance(),
pool.oracle(),
alice.address,
slot0.sqrtPriceX96,
amount_in_max,
amount_out_min,
sqrt_price_limit_x96,
deadline,
)
initializer.initializePoolSqrtPriceX96(params, sender=sender)

result = pool.state()
assert pytest.approx(result.sqrtPriceX96, rel=1e-3) == slot0.sqrtPriceX96


def test_initializer_initialize_pool_sqrt_price_x96__reverts_when_token0_greater_than_token1(
Expand All @@ -114,7 +372,7 @@ def test_initializer_initialize_pool_sqrt_price_x96__reverts_when_token0_greater

slot0 = mock_univ3_pool.slot0()
state = pool.state()
assert slot0.sqrtPriceX96 != state.sqrtPriceX96
assert slot0.sqrtPriceX96 < state.sqrtPriceX96
assert state.liquidity == MINIMUM_LIQUIDITY**2

amount_in_max = 2**256 - 1
Expand Down

0 comments on commit aeca903

Please sign in to comment.