diff --git a/scripts/experiments/max_newton_D.ipynb b/scripts/experiments/max_newton_D.ipynb index dc206aef..48a8d667 100644 --- a/scripts/experiments/max_newton_D.ipynb +++ b/scripts/experiments/max_newton_D.ipynb @@ -2,69 +2,182 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ - "import boa" + "import boa\n", + "%load_ext boa.ipython" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "<../../contracts/experimental/CurveCryptoMath2MAX.vy at 0x0880cf17Bd263d3d3a5c09D2D86cCecA3CcbD97c, compiled with vyper-0.3.10+9136169>" + "" ] }, - "execution_count": 3, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "math_contract = boa.load(\"../../contracts/experimental/CurveCryptoMath2MAX.vy\")\n", - "math_contract" + "%%vyper MAXNewton_D\n", + "\n", + "# pragma version 0.3.10\n", + "# pragma optimize gas\n", + "# pragma evm-version paris\n", + "\n", + "\n", + "N_COINS: constant(uint256) = 2\n", + "A_MULTIPLIER: constant(uint256) = 10000\n", + "\n", + "MIN_GAMMA: constant(uint256) = 10**10\n", + "MAX_GAMMA_SMALL: constant(uint256) = 2 * 10**16\n", + "MAX_GAMMA: constant(uint256) = 199 * 10**15 # 1.99 * 10**17\n", + "\n", + "MIN_A: constant(uint256) = N_COINS**N_COINS * A_MULTIPLIER / 10\n", + "MAX_A: constant(uint256) = N_COINS**N_COINS * A_MULTIPLIER * 1000\n", + "\n", + "MAX_ITER: constant(uint256) = 255\n", + "\n", + "\n", + "@external\n", + "@view\n", + "def newton_D() -> (\n", + " uint256[MAX_ITER],\n", + " uint256[MAX_ITER],\n", + " uint256[MAX_ITER],\n", + " uint256[MAX_ITER],\n", + " uint256[MAX_ITER],\n", + " uint256[MAX_ITER],\n", + " uint256[MAX_ITER],\n", + " uint256[MAX_ITER]\n", + "):\n", + " \"\"\"\n", + " Finding the invariant using Newton method.\n", + " ANN is higher by the factor A_MULTIPLIER\n", + " ANN is already A * N**N\n", + " \"\"\"\n", + "\n", + " # # Safety checks\n", + " # assert ANN > MIN_A - 1 and ANN < MAX_A + 1 # dev: unsafe values A\n", + " # assert gamma > MIN_GAMMA - 1 and gamma < MAX_GAMMA + 1 # dev: unsafe values gamma\n", + "\n", + " # # Initial value of invariant D is that for constant-product invariant\n", + " # x: uint256[N_COINS] = x_unsorted\n", + " # if x[0] < x[1]:\n", + " # x = [x_unsorted[1], x_unsorted[0]]\n", + "\n", + " # assert x[0] > 10**9 - 1 and x[0] < 10**15 * 10**18 + 1 # dev: unsafe values x[0]\n", + " # assert unsafe_div(x[1] * 10**18, x[0]) > 10**14 - 1 # dev: unsafe values x[i] (input)\n", + "\n", + " ANN: uint256 = MAX_A\n", + " gamma: uint256 = MAX_GAMMA\n", + "\n", + " x: uint256[N_COINS] = [10**15 * 10**18, 10**15 * 10**18]\n", + " S: uint256 = unsafe_add(x[0], x[1]) # can unsafe add here because we checked x[0] bounds\n", + " D: uint256 = N_COINS * isqrt(unsafe_mul(x[0], x[1]))\n", + "\n", + " __g1k0: uint256 = gamma + 10**18\n", + " diff: uint256 = 0\n", + "\n", + " K0_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + " _g1k0_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + " mul1_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + " mul2_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + " neg_fprime_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + " D_plus_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + " D_minus_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + " D_iter: uint256[MAX_ITER] = empty(uint256[MAX_ITER])\n", + "\n", + " for i in range(MAX_ITER):\n", + " D_prev: uint256 = D\n", + " assert D > 0\n", + " # Unsafe division by D and D_prev is now safe\n", + "\n", + " # K0: uint256 = 10**18\n", + " # for _x in x:\n", + " # K0 = K0 * _x * N_COINS / D\n", + " # collapsed for 2 coins\n", + " K0: uint256 = unsafe_div(unsafe_div((10**18 * N_COINS**2) * x[0], D) * x[1], D)\n", + "\n", + " _g1k0: uint256 = __g1k0\n", + " if _g1k0 > K0:\n", + " _g1k0 = unsafe_add(unsafe_sub(_g1k0, K0), 1) # > 0\n", + " else:\n", + " _g1k0 = unsafe_add(unsafe_sub(K0, _g1k0), 1) # > 0\n", + " # K0 is greater than 0\n", + " # _g1k0 is greater than 0\n", + "\n", + " # D / (A * N**N) * _g1k0**2 / gamma**2\n", + " mul1: uint256 = unsafe_div(unsafe_div(unsafe_div(10**18 * D, gamma) * _g1k0, gamma) * _g1k0 * A_MULTIPLIER, ANN)\n", + "\n", + " # 2*N*K0 / _g1k0\n", + " mul2: uint256 = unsafe_div(((2 * 10**18) * N_COINS) * K0, _g1k0)\n", + "\n", + " # calculate neg_fprime. here K0 > 0 is being validated (safediv).\n", + " neg_fprime: uint256 = (\n", + " S +\n", + " unsafe_div(S * mul2, 10**18) +\n", + " mul1 * N_COINS / K0 -\n", + " unsafe_div(mul2 * D, 10**18)\n", + " )\n", + "\n", + " # D -= f / fprime; neg_fprime safediv being validated\n", + " D_plus: uint256 = D * (neg_fprime + S) / neg_fprime\n", + " D_minus: uint256 = unsafe_div(D * D, neg_fprime)\n", + " if 10**18 > K0:\n", + " D_minus += unsafe_div(unsafe_div(D * unsafe_div(mul1, neg_fprime), 10**18) * unsafe_sub(10**18, K0), K0)\n", + " else:\n", + " D_minus -= unsafe_div(unsafe_div(D * unsafe_div(mul1, neg_fprime), 10**18) * unsafe_sub(K0, 10**18), K0)\n", + "\n", + " if D_plus > D_minus:\n", + " D = unsafe_sub(D_plus, D_minus)\n", + " else:\n", + " D = unsafe_div(unsafe_sub(D_minus, D_plus), 2)\n", + "\n", + " K0_iter[i] = K0\n", + " _g1k0_iter[i] = _g1k0\n", + " mul1_iter[i] = mul1\n", + " mul2_iter[i] = mul2\n", + " neg_fprime_iter[i] = neg_fprime\n", + " D_plus_iter[i] = D_plus\n", + " D_minus_iter[i] = D_minus\n", + " D_iter[i] = D\n", + "\n", + " return K0_iter, _g1k0_iter, mul1_iter, mul2_iter, neg_fprime_iter, D_plus_iter, D_minus_iter, D_iter" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ + "math_contract = MAXNewton_D.deploy()\n", "output = math_contract.newton_D()" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "255" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "K0_iter = output[0]\n", - "K0_iter = output[1]\n", - "_g1k0_iter = output[2]\n", - "mul1_iter = output[3]\n", - "mul2_iter = output[4]\n", - "neg_fprime_iter = output[5]\n", - "D_plus_iter = output[6]\n", - "D_minus_iter = output[7]\n", - "D_iter = output[8]" + "_g1k0_iter = output[1]\n", + "mul1_iter = output[2]\n", + "mul2_iter = output[3]\n", + "neg_fprime_iter = output[4]\n", + "D_plus_iter = output[5]\n", + "D_minus_iter = output[6]\n", + "D_iter = output[7]" ] }, { @@ -88,280 +201,6 @@ "len(D_iter)" ] }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000,\n", - " 2000000000000000000000000000000000]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "D_iter" - ] - }, { "cell_type": "code", "execution_count": null,