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

add features and tests #2

Merged
merged 76 commits into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
44a7bf8
bump gauge version
bout3fiddy Oct 5, 2023
42bff31
feat: add exchange_received_split experimental idea; fix: upkeep xcp …
bout3fiddy Oct 5, 2023
b0aecd0
add docstrings to exchange_received_split
bout3fiddy Oct 5, 2023
be077a2
add distinction between split_in and split_out
bout3fiddy Oct 6, 2023
d3a6282
fix: isqrt precision issues; tests
bout3fiddy Oct 9, 2023
58ff178
fix extra accounting of dx received
bout3fiddy Oct 9, 2023
d879e4c
add cicd
bout3fiddy Oct 11, 2023
ca4317c
update boa
bout3fiddy Oct 11, 2023
7797ad4
fix path
bout3fiddy Oct 11, 2023
39963c8
update limits in tests
bout3fiddy Oct 11, 2023
d2e7fec
remove print; ignore flake8
bout3fiddy Oct 11, 2023
aea8d70
add fuzz
bout3fiddy Oct 11, 2023
97a644b
begin stateful tests
bout3fiddy Nov 1, 2023
6ab6f4a
fix: rearrange calcs to avoid overflow
bout3fiddy Nov 1, 2023
3c3e29a
fix: ramp A gamma with old xp[i] value and not new one
bout3fiddy Nov 1, 2023
4d76e11
claim admin virtual balances as well
bout3fiddy Nov 1, 2023
e601564
only proportion goes to admin lp virtual balance
bout3fiddy Nov 2, 2023
71c58d6
introduce spot portfolio and account for portfolio balance in _transf…
bout3fiddy Nov 2, 2023
05d0b4f
only msg.sender can deposit or withdraw from spot wallet
bout3fiddy Nov 2, 2023
f901e54
Change range of params for get_y unitary test.
Nov 5, 2023
3be3a0f
fix: error using cached price instead of uncached for price oracle
bout3fiddy Nov 6, 2023
244144f
Merge branch 'feat/tests' of https://github.com/curvefi/twocrypto-ng …
bout3fiddy Nov 6, 2023
5eceae4
change max limits for gamma and A (found by filipp after rigorous tes…
bout3fiddy Nov 6, 2023
53a8e46
use pragma instead
bout3fiddy Nov 6, 2023
4352c72
fix: redesign exchange_received_split to relax out amounts
bout3fiddy Nov 6, 2023
026afab
fix: use correct amounts
bout3fiddy Nov 6, 2023
5500457
goodbye spot wallet idea. you were good but not good enough
bout3fiddy Nov 8, 2023
0e33774
fix limits and remove spot wallet tests
bout3fiddy Nov 8, 2023
d102eaf
remove ape
bout3fiddy Nov 9, 2023
6a22fe4
remove mentions of tricrypto
bout3fiddy Nov 9, 2023
70c89a4
remove k reference
bout3fiddy Nov 9, 2023
4cabeeb
Fix get_y operation order for precision and overflow prevention.
Nov 12, 2023
b0079e3
add test for fixed precision issues
bout3fiddy Nov 14, 2023
2f3f931
pack last timestamp into one uint256 and add tests
bout3fiddy Nov 14, 2023
52c03cb
remove asserts because packed2 values are timestamps so no need to do…
bout3fiddy Nov 14, 2023
407fd0f
claim fees before remove liq one
bout3fiddy Nov 14, 2023
91122cd
Add multiple get_y test instances, uncomment asserts.
Nov 15, 2023
2ff7b80
Merge branch 'feat/tests' of github.com:curvefi/twocrypto-ng into fea…
Nov 15, 2023
92a0435
unsafe add nonce
bout3fiddy Nov 22, 2023
ef3491c
Merge branch 'feat/tests' of https://github.com/curvefi/twocrypto-ng …
bout3fiddy Nov 22, 2023
fe68f2c
reduce unnecessary storage reads in some conditions in _claim_admin_fees
bout3fiddy Nov 22, 2023
6fce03c
use unsafe sub for +ve timedeltas
bout3fiddy Nov 22, 2023
f4ab108
gas: remove unnecessary re-read of storage in remove_liquidity
bout3fiddy Nov 22, 2023
eb4acb3
add fuzz to this test
bout3fiddy Nov 22, 2023
616a278
claim fees before deposit
bout3fiddy Nov 22, 2023
ec5b122
remove double mul of precisions[0]
bout3fiddy Nov 22, 2023
6d80da0
fix: remove double mul correctly :P
bout3fiddy Nov 22, 2023
ba1dc63
remove call to reduction coefficient
bout3fiddy Nov 22, 2023
a3388cd
fix: remove double precision division
bout3fiddy Nov 22, 2023
d500585
fix: use correct method_id
bout3fiddy Nov 22, 2023
7cabdbc
use correct method
bout3fiddy Nov 22, 2023
fd2e505
call ma_time instead of ma_half_time'
bout3fiddy Nov 22, 2023
d8021ec
check A and gamma in implementation constructor and not in factory to…
bout3fiddy Nov 22, 2023
c81dbdc
use DynArrays and save a bunch of gas while deploying pool
bout3fiddy Nov 22, 2023
5ae137d
use immutables
bout3fiddy Nov 22, 2023
f9958d3
log new approval event
bout3fiddy Nov 22, 2023
4a95cc1
unsafe divs and muls in get_y
bout3fiddy Nov 23, 2023
0692ba9
add one unsafe add
bout3fiddy Nov 23, 2023
ac588b0
gas: newton_D
bout3fiddy Nov 23, 2023
7875cae
check nonzero math impl
bout3fiddy Nov 23, 2023
9487057
add salt to eip712 tyephash
bout3fiddy Nov 23, 2023
adfed8d
add more newton_D checks
bout3fiddy Nov 24, 2023
5a03822
fix: some errors; github workflow
bout3fiddy Nov 24, 2023
359951f
fix: return int instead of array of Decimal types
bout3fiddy Nov 24, 2023
e931743
Update test_newton_D_ref.py
Nov 30, 2023
cf74f17
Fix newton_D_ref test params.
Dec 4, 2023
def5008
Fix newton_D_ref test param limits.
Dec 4, 2023
75c46c1
Merge branch 'feat/tests' of github.com:curvefi/twocrypto-ng into fea…
Dec 4, 2023
2b46e41
Update newton_D test.
Dec 5, 2023
4cc4b74
fix test MAX_A lim and fix order of unpacking in amm impl constructor
bout3fiddy Dec 15, 2023
ab2080b
remove admin fee auto claim in add_liquidity
bout3fiddy Dec 16, 2023
7092010
pack precisions and name packed gamma and A var better
bout3fiddy Dec 16, 2023
036a8e8
fix math tests
bout3fiddy Dec 18, 2023
6246ad9
stateful tests and other tests
bout3fiddy Dec 23, 2023
50b381b
fix: lp price isqrt input
bout3fiddy Dec 23, 2023
b8601ae
fix: get_p test
bout3fiddy Dec 23, 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
11 changes: 11 additions & 0 deletions .github/workflows/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: pre-commit

on: [pull_request, push]

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v4
- uses: pre-commit/[email protected]
30 changes: 30 additions & 0 deletions .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: unit-tests-boa

on: ["push", "pull_request"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just pick either push or pull_request, using both generates twice the same job for every commit in a PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image


env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
boa-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Cache Compiler Installations
uses: actions/cache@v2
with:
path: |
~/.vvm
key: compiler-cache

- name: Setup Python 3.10.4
bout3fiddy marked this conversation as resolved.
Show resolved Hide resolved
uses: actions/setup-python@v2
with:
python-version: 3.10.4

- name: Install Requirements
run: pip install -r requirements.txt

- name: Run Tests
run: python -m pytest tests/ -n auto
59 changes: 0 additions & 59 deletions ape-config.yaml

This file was deleted.

195 changes: 195 additions & 0 deletions contracts/experimental/n=2.vy
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# @version 0.3.10


N_COINS: constant(uint256) = 2
PRECISION: constant(uint256) = 10 ** 18 # The precision to convert to
A_MULTIPLIER: constant(uint256) = 10000

MIN_GAMMA: constant(uint256) = 10**10
MAX_GAMMA: constant(uint256) = 2 * 10**15

MIN_A: constant(uint256) = N_COINS**N_COINS * A_MULTIPLIER / 10
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:
"""
Calculating x[i] given other balances x[0..N_COINS-1] and invariant D
ANN = A * N**N
"""
# 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

x_j: uint256 = x[1 - i]
y: uint256 = D**2 / (x_j * N_COINS**2)
K0_i: uint256 = (10**18 * N_COINS) * x_j / D
# S_i = x_j

# frac = x_j * 1e18 / D => frac = K0_i / N_COINS
# assert (K0_i > 10**16*N_COINS - 1) and (K0_i < 10**20*N_COINS + 1) # dev: unsafe values x[i]

# x_sorted: uint256[N_COINS] = x
# x_sorted[i] = 0
# x_sorted = self.sort(x_sorted) # From high to low
# x[not i] instead of x_sorted since x_soted has only 1 element

convergence_limit: uint256 = max(max(x_j / 10**14, D / 10**14), 100)

for j in range(255):
y_prev: uint256 = y

K0: uint256 = K0_i * y * N_COINS / D
S: uint256 = x_j + y

_g1k0: uint256 = gamma + 10**18
if _g1k0 > K0:
_g1k0 = _g1k0 - K0 + 1
else:
_g1k0 = K0 - _g1k0 + 1

# D / (A * N**N) * _g1k0**2 / gamma**2
mul1: uint256 = 10**18 * D / gamma * _g1k0 / gamma * _g1k0 * A_MULTIPLIER / ANN

# 2*K0 / _g1k0
mul2: uint256 = 10**18 + (2 * 10**18) * K0 / _g1k0

yfprime: uint256 = 10**18 * y + S * mul2 + mul1
_dyfprime: uint256 = D * mul2
if yfprime < _dyfprime:
y = y_prev / 2
continue
else:
yfprime -= _dyfprime
fprime: uint256 = yfprime / y

# y -= f / f_prime; y = (y * fprime - f) / fprime
# y = (yfprime + 10**18 * D - 10**18 * S) // fprime + mul1 // fprime * (10**18 - K0) // K0
y_minus: uint256 = mul1 / fprime
y_plus: uint256 = (yfprime + 10**18 * D) / fprime + y_minus * 10**18 / K0
y_minus += 10**18 * S / fprime

if y_plus < y_minus:
y = y_prev / 2
else:
y = y_plus - y_minus

diff: uint256 = 0
if y > y_prev:
diff = y - y_prev
else:
diff = y_prev - y
if diff < max(convergence_limit, y / 10**14):
frac: uint256 = y * 10**18 / D
assert (frac > 10**16 - 1) and (frac < 10**20 + 1) # dev: unsafe value for y
return y

raise "Did not converge"

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


@internal
@pure
def geometric_mean(unsorted_x: uint256[N_COINS], sort: bool) -> uint256:
"""
(x[0] * x[1] * ...) ** (1/N)
"""
x: uint256[N_COINS] = unsorted_x
if sort and x[0] < x[1]:
x = [unsorted_x[1], unsorted_x[0]]
D: uint256 = x[0]
diff: uint256 = 0
for i in range(255):
D_prev: uint256 = D
# tmp: uint256 = 10**18
# for _x in x:
# tmp = tmp * _x / D
# D = D * ((N_COINS - 1) * 10**18 + tmp) / (N_COINS * 10**18)
# line below makes it for 2 coins
D = unsafe_div(D + x[0] * x[1] / D, N_COINS)
if D > D_prev:
diff = unsafe_sub(D, D_prev)
else:
diff = unsafe_sub(D_prev, D)
if diff <= 1 or diff * 10**18 < D:
return D
raise "Did not converge"


@external
@view
def newton_D(ANN: uint256, gamma: uint256, x_unsorted: uint256[N_COINS]) -> uint256:
"""
Finding the invariant using Newton method.
ANN is higher by the factor A_MULTIPLIER
ANN is already A * N**N

Currently uses 60k gas
"""

# Initial value of invariant D is that for constant-product invariant
x: uint256[N_COINS] = x_unsorted
if x[0] < x[1]:
x = [x_unsorted[1], x_unsorted[0]]

D: uint256 = N_COINS * self.geometric_mean(x, False)
S: uint256 = x[0] + x[1]
__g1k0: uint256 = gamma + 10**18

for i in range(255):
D_prev: uint256 = D
assert D > 0
# Unsafe ivision by D is now safe

# K0: uint256 = 10**18
# for _x in x:
# K0 = K0 * _x * N_COINS / D
# collapsed for 2 coins
K0: uint256 = unsafe_div(unsafe_div((10**18 * N_COINS**2) * x[0], D) * x[1], D)

_g1k0: uint256 = __g1k0
if _g1k0 > K0:
_g1k0 = unsafe_sub(_g1k0, K0) + 1 # > 0
else:
_g1k0 = unsafe_sub(K0, _g1k0) + 1 # > 0

# D / (A * N**N) * _g1k0**2 / gamma**2
mul1: uint256 = unsafe_div(unsafe_div(unsafe_div(10**18 * D, gamma) * _g1k0, gamma) * _g1k0 * A_MULTIPLIER, ANN)

# 2*N*K0 / _g1k0
mul2: uint256 = unsafe_div(((2 * 10**18) * N_COINS) * K0, _g1k0)

neg_fprime: uint256 = (S + unsafe_div(S * mul2, 10**18)) + mul1 * N_COINS / K0 - unsafe_div(mul2 * D, 10**18)

# D -= f / fprime
D_plus: uint256 = D * (neg_fprime + S) / neg_fprime
D_minus: uint256 = D*D / neg_fprime
if 10**18 > K0:
D_minus += unsafe_div(D * (mul1 / neg_fprime), 10**18) * unsafe_sub(10**18, K0) / K0
else:
D_minus -= unsafe_div(D * (mul1 / neg_fprime), 10**18) * unsafe_sub(K0, 10**18) / K0

if D_plus > D_minus:
D = unsafe_sub(D_plus, D_minus)
else:
D = unsafe_div(unsafe_sub(D_minus, D_plus), 2)

diff: uint256 = 0
if D > D_prev:
diff = unsafe_sub(D, D_prev)
else:
diff = unsafe_sub(D_prev, D)
if diff * 10**14 < max(10**16, D): # Could reduce precision for gas efficiency here
# Test that we are safe with the next newton_y
for _x in x:
frac: uint256 = _x * 10**18 / D
return D

raise "Did not converge"
Loading
Loading