Skip to content

Commit

Permalink
test: ensuring old bounds behavior is unchanged
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertoCentonze committed Apr 16, 2024
1 parent 5b9f008 commit 05e7a8a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 21 deletions.
2 changes: 1 addition & 1 deletion contracts/mocks/newton_y_large_gamma.vy
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ def newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i: u
if gamma > MAX_GAMMA_SMALL:
lim_mul = unsafe_div(unsafe_mul(lim_mul, MAX_GAMMA_SMALL), gamma) # smaller than 100.0

iterations: uint256 = 0
y: uint256 = 0
iterations: uint256 = 0

y, iterations = self._newton_y(ANN, gamma, x, D, i, lim_mul)
frac: uint256 = y * 10**18 / D
Expand Down
13 changes: 8 additions & 5 deletions contracts/mocks/newton_y_small_gamma.vy
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MAX_A: constant(uint256) = N_COINS**N_COINS * A_MULTIPLIER * 1000

@internal
@pure
def _newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i: uint256) -> uint256:
def _newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i: uint256) -> (uint256, uint256):
"""
Calculating x[i] given other balances x[0..N_COINS-1] and invariant D
ANN = A * N**N
Expand Down Expand Up @@ -74,22 +74,25 @@ def _newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i:
diff = y_prev - y

if diff < max(convergence_limit, y / 10**14):
return y
return y, j

raise "Did not converge"


@external
@pure
def newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i: uint256) -> uint256:
def newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i: uint256) -> (uint256, uint256):

# Safety checks
assert ANN > MIN_A - 1 and ANN < MAX_A + 1 # dev: unsafe values A
assert gamma > MIN_GAMMA - 1 and gamma < MAX_GAMMA + 1 # dev: unsafe values gamma
assert D > 10**17 - 1 and D < 10**15 * 10**18 + 1 # dev: unsafe values D

y: uint256 = self._newton_y(ANN, gamma, x, D, i)
y: uint256 = 0
iterations: uint256 = 0

y, iterations = self._newton_y(ANN, gamma, x, D, i)
frac: uint256 = y * 10**18 / D
assert (frac >= 10**16 - 1) and (frac < 10**20 + 1) # dev: unsafe value for y

return y
return y, iterations
40 changes: 25 additions & 15 deletions tests/unitary/math/test_newton_y.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import boa
import pytest
from hypothesis import given, settings
from hypothesis import event, given, settings
from hypothesis import strategies as st

N_COINS = 2
Expand All @@ -12,8 +12,10 @@
MIN_A = int(N_COINS**N_COINS * A_MUL / 10)
MAX_A = int(N_COINS**N_COINS * A_MUL * 1000)

MIN_GAMMA = 10**10
MAX_GAMMA = 3 * 10**17
# Old bounds for gamma
# should be used only when comparing convergence with the old version
MIN_GAMMA_CMP = 10**10
MAX_GAMMA_CMP = 2 * 10**15


@pytest.fixture(scope="module")
Expand All @@ -23,7 +25,7 @@ def math_large_gamma():

@pytest.fixture(scope="module")
def math_small_gamma():
return boa.load("contracts/mock/newton_y_small_gamma.vy")
return boa.load("contracts/mocks/newton_y_small_gamma.vy")


@given(
Expand All @@ -37,17 +39,25 @@ def math_small_gamma():
yD=st.integers(
min_value=10**17 // 2, max_value=10**19 // 2
), # <- ratio 1e18 * y/D, typically 1e18 * 1
gamma=st.integers(min_value=MIN_GAMMA, max_value=MAX_GAMMA),
gamma=st.integers(min_value=MIN_GAMMA_CMP, max_value=MAX_GAMMA_CMP),
j=st.integers(min_value=0, max_value=1),
)
@settings(max_examples=MAX_SAMPLES, deadline=None)
def test_iteration_diff(math_large_gamma, A, D, xD, yD, gamma, j):
pass
# TODO: make a test that:
# - measures how many iterations it takes for the
# old value to converge between the two versions
# - makes sure that we're converging to the correct value
# - use hypothesis.event to have some clear statistics about
# the differences in divergence
# X = [D * xD // 10**18, D * yD // 10**18]
# math_large_gamma.newton_y(A, gamma, X, D, j)
def test_newton_y_equivalence(
math_small_gamma, math_large_gamma, A, D, xD, yD, gamma, j
):
"""
Tests whether the newton_y function converges to the same
value for both the old and new versions
"""
X = [D * xD // 10**18, D * yD // 10**18]
y_small, iterations_old = math_small_gamma.newton_y(A, gamma, X, D, j)
y_large, iterations_new = math_large_gamma.newton_y(A, gamma, X, D, j)

# print(math_large_gamma.internal._newton_y)

event(f"converges in {iterations_new} iterations")

# create events depending on the differences between iterations
assert iterations_old - iterations_new == 0
assert y_small == y_large

0 comments on commit 05e7a8a

Please sign in to comment.