From c674a00901c95a9345ea0a4a1118eb7d0807c16a Mon Sep 17 00:00:00 2001 From: Roman Agureev Date: Mon, 17 Oct 2022 15:38:58 +0300 Subject: [PATCH 1/3] update simulation --- tests/simulation.py | 61 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/tests/simulation.py b/tests/simulation.py index 7339c405..a84d0b30 100644 --- a/tests/simulation.py +++ b/tests/simulation.py @@ -4,7 +4,7 @@ class Curve: Python model of Curve pool math. """ - def __init__(self, A, D, n, p=None, tokens=None): + def __init__(self, A, D, n, p=None, tokens=None, fee=10 ** 7, admin_fee=0): """ A: Amplification coefficient D: Total deposit size @@ -13,7 +13,8 @@ def __init__(self, A, D, n, p=None, tokens=None): """ self.A = A # actually A * n ** (n - 1) because it's an invariant self.n = n - self.fee = 10 ** 7 + self.fee = fee + self.admin_fee = admin_fee if p: self.p = p else: @@ -115,12 +116,51 @@ def exchange(self, i, j, dx): y = self.y(i, j, x) dy = xp[j] - y fee = dy * self.fee // 10 ** 10 + admin_fee = fee * self.admin_fee // 10 ** 10 assert dy > 0 self.x[i] = x * 10 ** 18 // self.p[i] - self.x[j] = (y + fee) * 10 ** 18 // self.p[j] + self.x[j] = (y + fee - admin_fee) * 10 ** 18 // self.p[j] return dy - fee - def remove_liquidity_imbalance(self, amounts): + def add_liquidity(self, amounts, update_values=False): + _fee = self.fee * self.n // (4 * (self.n - 1)) + + old_balances = self.x + D0 = self.D() + + new_balances = old_balances + for i in range(self.n): + new_balances[i] += amounts[i] + self.x = new_balances + D1 = self.D() + assert D1 > D0 + + fees = [0] * self.n + if self.tokens > 0: + real_balances = [0] * 3 + for i in range(self.n): + ideal_balance = D1 * old_balances[i] // D0 + difference = abs(ideal_balance - new_balances[i]) + fees[i] = _fee * difference // 10 ** 10 + real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10 ** 10) + new_balances[i] -= fees[i] + self.x = new_balances + D2 = self.D() + mint_amount = self.tokens * (D2 - D0) // D0 + + self.x = real_balances + else: + self.x = new_balances + mint_amount = D1 # Take the dust if there was any + + if not update_values: + self.x = old_balances + else: + self.tokens += mint_amount + + return mint_amount + + def remove_liquidity_imbalance(self, amounts, update_values=False): _fee = self.fee * self.n // (4 * (self.n - 1)) old_balances = self.x @@ -132,17 +172,24 @@ def remove_liquidity_imbalance(self, amounts): D1 = self.D() self.x = old_balances fees = [0] * self.n + real_balances = [0] * self.n for i in range(self.n): ideal_balance = D1 * old_balances[i] // D0 difference = abs(ideal_balance - new_balances[i]) fees[i] = _fee * difference // 10 ** 10 + real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10 ** 10) new_balances[i] -= fees[i] self.x = new_balances D2 = self.D() - self.x = old_balances token_amount = (D0 - D2) * self.tokens // D0 + self.x = real_balances + if not update_values: + self.x = old_balances + else: + self.tokens -= token_amount + return token_amount def calc_withdraw_one_coin(self, token_amount, i): @@ -157,3 +204,7 @@ def calc_withdraw_one_coin(self, token_amount, i): dy = xp[i] - self.y_D(i, D1) return dy - dy * fee // 10 ** 10 + + def get_virtual_price(self): + return self.D() * 10 ** 18 // self.tokens + From 2494153c7236e49e78191968b39309ba4c380c47 Mon Sep 17 00:00:00 2001 From: Roman Agureev Date: Mon, 17 Oct 2022 16:01:56 +0300 Subject: [PATCH 2/3] style: fix --- tests/simulation.py | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/tests/simulation.py b/tests/simulation.py index a84d0b30..0058eb29 100644 --- a/tests/simulation.py +++ b/tests/simulation.py @@ -4,7 +4,7 @@ class Curve: Python model of Curve pool math. """ - def __init__(self, A, D, n, p=None, tokens=None, fee=10 ** 7, admin_fee=0): + def __init__(self, A, D, n, p=None, tokens=None, fee=10**7, admin_fee=0): """ A: Amplification coefficient D: Total deposit size @@ -18,15 +18,15 @@ def __init__(self, A, D, n, p=None, tokens=None, fee=10 ** 7, admin_fee=0): if p: self.p = p else: - self.p = [10 ** 18] * n + self.p = [10**18] * n if isinstance(D, list): self.x = D else: - self.x = [D // n * 10 ** 18 // _p for _p in self.p] + self.x = [D // n * 10**18 // _p for _p in self.p] self.tokens = tokens def xp(self): - return [x * p // 10 ** 18 for x, p in zip(self.x, self.p)] + return [x * p // 10**18 for x, p in zip(self.x, self.p)] def D(self): """ @@ -76,7 +76,7 @@ def y(self, i, j, x): y = D while abs(y - y_prev) > 1: y_prev = y - y = (y ** 2 + c) // (2 * y + b) + y = (y**2 + c) // (2 * y + b) return y # the result is in underlying units too def y_D(self, i, _D): @@ -102,7 +102,7 @@ def y_D(self, i, _D): y = _D while abs(y - y_prev) > 1: y_prev = y - y = (y ** 2 + c) // (2 * y + b - _D) + y = (y**2 + c) // (2 * y + b - _D) return y # the result is in underlying units too def dy(self, i, j, dx): @@ -115,11 +115,11 @@ def exchange(self, i, j, dx): x = xp[i] + dx y = self.y(i, j, x) dy = xp[j] - y - fee = dy * self.fee // 10 ** 10 - admin_fee = fee * self.admin_fee // 10 ** 10 + fee = dy * self.fee // 10**10 + admin_fee = fee * self.admin_fee // 10**10 assert dy > 0 - self.x[i] = x * 10 ** 18 // self.p[i] - self.x[j] = (y + fee - admin_fee) * 10 ** 18 // self.p[j] + self.x[i] = x * 10**18 // self.p[i] + self.x[j] = (y + fee - admin_fee) * 10**18 // self.p[j] return dy - fee def add_liquidity(self, amounts, update_values=False): @@ -141,8 +141,8 @@ def add_liquidity(self, amounts, update_values=False): for i in range(self.n): ideal_balance = D1 * old_balances[i] // D0 difference = abs(ideal_balance - new_balances[i]) - fees[i] = _fee * difference // 10 ** 10 - real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10 ** 10) + fees[i] = _fee * difference // 10**10 + real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10**10) new_balances[i] -= fees[i] self.x = new_balances D2 = self.D() @@ -176,8 +176,8 @@ def remove_liquidity_imbalance(self, amounts, update_values=False): for i in range(self.n): ideal_balance = D1 * old_balances[i] // D0 difference = abs(ideal_balance - new_balances[i]) - fees[i] = _fee * difference // 10 ** 10 - real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10 ** 10) + fees[i] = _fee * difference // 10**10 + real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10**10) new_balances[i] -= fees[i] self.x = new_balances D2 = self.D() @@ -195,7 +195,7 @@ def remove_liquidity_imbalance(self, amounts, update_values=False): def calc_withdraw_one_coin(self, token_amount, i): xp = self.xp() if self.fee: - fee = self.fee - self.fee * xp[i] // sum(xp) + 5 * 10 ** 5 + fee = self.fee - self.fee * xp[i] // sum(xp) + 5 * 10**5 else: fee = 0 @@ -203,8 +203,7 @@ def calc_withdraw_one_coin(self, token_amount, i): D1 = D0 - token_amount * D0 // self.tokens dy = xp[i] - self.y_D(i, D1) - return dy - dy * fee // 10 ** 10 + return dy - dy * fee // 10**10 def get_virtual_price(self): - return self.D() * 10 ** 18 // self.tokens - + return self.D() * 10**18 // self.tokens From 164f8d2a979c62ea8471f9597dfc786538c064ce Mon Sep 17 00:00:00 2001 From: Roman Agureev Date: Mon, 17 Oct 2022 19:34:34 +0300 Subject: [PATCH 3/3] fix: black --- tests/simulation.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/simulation.py b/tests/simulation.py index 0058eb29..42d1e239 100644 --- a/tests/simulation.py +++ b/tests/simulation.py @@ -4,7 +4,7 @@ class Curve: Python model of Curve pool math. """ - def __init__(self, A, D, n, p=None, tokens=None, fee=10**7, admin_fee=0): + def __init__(self, A, D, n, p=None, tokens=None, fee=10 ** 7, admin_fee=0): """ A: Amplification coefficient D: Total deposit size @@ -18,15 +18,15 @@ def __init__(self, A, D, n, p=None, tokens=None, fee=10**7, admin_fee=0): if p: self.p = p else: - self.p = [10**18] * n + self.p = [10 ** 18] * n if isinstance(D, list): self.x = D else: - self.x = [D // n * 10**18 // _p for _p in self.p] + self.x = [D // n * 10 ** 18 // _p for _p in self.p] self.tokens = tokens def xp(self): - return [x * p // 10**18 for x, p in zip(self.x, self.p)] + return [x * p // 10 ** 18 for x, p in zip(self.x, self.p)] def D(self): """ @@ -76,7 +76,7 @@ def y(self, i, j, x): y = D while abs(y - y_prev) > 1: y_prev = y - y = (y**2 + c) // (2 * y + b) + y = (y ** 2 + c) // (2 * y + b) return y # the result is in underlying units too def y_D(self, i, _D): @@ -102,7 +102,7 @@ def y_D(self, i, _D): y = _D while abs(y - y_prev) > 1: y_prev = y - y = (y**2 + c) // (2 * y + b - _D) + y = (y ** 2 + c) // (2 * y + b - _D) return y # the result is in underlying units too def dy(self, i, j, dx): @@ -115,11 +115,11 @@ def exchange(self, i, j, dx): x = xp[i] + dx y = self.y(i, j, x) dy = xp[j] - y - fee = dy * self.fee // 10**10 - admin_fee = fee * self.admin_fee // 10**10 + fee = dy * self.fee // 10 ** 10 + admin_fee = fee * self.admin_fee // 10 ** 10 assert dy > 0 - self.x[i] = x * 10**18 // self.p[i] - self.x[j] = (y + fee - admin_fee) * 10**18 // self.p[j] + self.x[i] = x * 10 ** 18 // self.p[i] + self.x[j] = (y + fee - admin_fee) * 10 ** 18 // self.p[j] return dy - fee def add_liquidity(self, amounts, update_values=False): @@ -141,8 +141,8 @@ def add_liquidity(self, amounts, update_values=False): for i in range(self.n): ideal_balance = D1 * old_balances[i] // D0 difference = abs(ideal_balance - new_balances[i]) - fees[i] = _fee * difference // 10**10 - real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10**10) + fees[i] = _fee * difference // 10 ** 10 + real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10 ** 10) new_balances[i] -= fees[i] self.x = new_balances D2 = self.D() @@ -176,8 +176,8 @@ def remove_liquidity_imbalance(self, amounts, update_values=False): for i in range(self.n): ideal_balance = D1 * old_balances[i] // D0 difference = abs(ideal_balance - new_balances[i]) - fees[i] = _fee * difference // 10**10 - real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10**10) + fees[i] = _fee * difference // 10 ** 10 + real_balances[i] = new_balances[i] - (fees[i] * self.admin_fee // 10 ** 10) new_balances[i] -= fees[i] self.x = new_balances D2 = self.D() @@ -195,7 +195,7 @@ def remove_liquidity_imbalance(self, amounts, update_values=False): def calc_withdraw_one_coin(self, token_amount, i): xp = self.xp() if self.fee: - fee = self.fee - self.fee * xp[i] // sum(xp) + 5 * 10**5 + fee = self.fee - self.fee * xp[i] // sum(xp) + 5 * 10 ** 5 else: fee = 0 @@ -203,7 +203,7 @@ def calc_withdraw_one_coin(self, token_amount, i): D1 = D0 - token_amount * D0 // self.tokens dy = xp[i] - self.y_D(i, D1) - return dy - dy * fee // 10**10 + return dy - dy * fee // 10 ** 10 def get_virtual_price(self): - return self.D() * 10**18 // self.tokens + return self.D() * 10 ** 18 // self.tokens