Uniswap V2
-
In this tutorial, we review the following:
- Swap
- Double-sided withdraw
- Double-sided deposit
- Single-sided withdraw
- Single-sided deposit
-
To download notebook to this tutorial, see here
from uniswappy import *import numpy as npimport matplotlib.pyplot as pltimport mathuser_nm = 'user_intro'eth_amount = 1000dai_amount = 1000000dai = ERC20("DAI", "0x111")eth = ERC20("ETH", "0x09")exchg_data = UniswapExchangeData(tkn0 = eth, tkn1 = dai, symbol="LP", address="0x011")
factory = UniswapFactory("ETH pool factory", "0x2")lp = factory.deploy(exchg_data)Join().apply(lp, user_nm, eth_amount, dai_amount)lp.summary()Given CPT formula
with 0.3% swap fee
Since L is preserved when swapping, the CPT swap formula with fee is given as
To determine swap amount, isolate
After performing some additional algebra, we get
Perform swap using dervation
Section titled “Perform swap using dervation”dy = 1000gamma = 997/1000x = lp.get_reserve(eth)y = lp.get_reserve(dai)
dx = (gamma*x*dy)/(y + gamma*dy)
print(f'We receive {dx:.5f} ETH for {dy} DAI')Perform swap using uniswappy
Section titled “Perform swap using uniswappy”out = Swap().apply(lp, dai, user_nm, dy)lp.summary()
print(f'We receive {out:.5f} ETH for {dy} DAI')L = lp.get_liquidity()x2 = lp.get_reserve(eth)y2 = lp.get_reserve(dai)
x_arr = np.arange(990, 1010, 0.01)y_arr = L**2/x_arr
fig, (ax) = plt.subplots(nrows=1, sharex=False, sharey=False, figsize=(10, 5))ax.plot(x_arr, y_arr, color = 'b',linestyle = 'dashdot', label='initial invest')ax.plot(x, y, 'ro', color='r')ax.plot(x2, y2, 'ro', color='g')
ax.hlines(y=y2, xmin=0, xmax=x2, linewidth=1, color='g', linestyle = 'dashed')ax.vlines(x = x2, ymin=0, ymax=y2, linewidth=1, color='g', linestyle = 'dashed')
ax.hlines(y= y, xmin=0, xmax=x, linewidth=1, color='r', linestyle = 'dashed')ax.vlines(x = x, ymin=0, ymax=y, linewidth=1, color='r', linestyle = 'dashed')
ax.annotate('post-swap', xy=(x2, y2),xytext=(x2+5, y2+5000), arrowprops=dict(facecolor='green',width=0.5,headwidth=10,headlength=10))ax.annotate('pre-swap', xy=(x, y),xytext=(x2+7, y2+2000), arrowprops=dict(facecolor='red',width=0.5,headwidth=10,headlength=10))
ax.set_title(f'CPT Price Curve Swap', fontsize=20)ax.set_ylabel(f'{dai.token_name} Reserve Amt', size=15)ax.set_xlabel(f'{eth.token_name} Reserve Amt', size=15)ax.set_xlim((990,1010))ax.set_ylim((992000,1008000))Doubled-sided withdraw
Section titled “Doubled-sided withdraw”dai = ERC20("DAI", "0x111")eth = ERC20("ETH", "0x09")exchg_data = UniswapExchangeData(tkn0 = eth, tkn1 = dai, symbol="LP", address="0x011")
factory = UniswapFactory("ETH pool factory", "0x2")lp = factory.deploy(exchg_data)Join().apply(lp, user_nm, eth_amount, dai_amount)lp.summary()dx = 1x = lp.get_reserve(eth)y = lp.get_reserve(dai)L = lp.get_liquidity()Given CPT formula
Price is determined as such
,
Given P above, calculate and while maintaining price integrity
,
,
,
,
,
Take RHS of CPT formula and deduct and from both and to maintain integrity of the price
CPT withdraw formula
Calculate withdraw using dervation
Section titled “Calculate withdraw using dervation”dL = dx*L/xdy = y*dL/Lnew_x = (x-dx)new_y = (y-dy)new_L = L-dL
print(f'The updated reserves are {new_x} ETH and {new_y} DAI, and the updated liquidity is {new_L:8f}')Perform withdraw using uniswappy
Section titled “Perform withdraw using uniswappy”RemoveLiquidity().apply(lp, eth, user_nm, dx)lp.summary()Doubled-sided deposit
Section titled “Doubled-sided deposit”dai = ERC20("DAI", "0x111")eth = ERC20("ETH", "0x09")exchg_data = UniswapExchangeData(tkn0 = eth, tkn1 = dai, symbol="LP", address="0x011")
factory = UniswapFactory("ETH pool factory", "0x2")lp = factory.deploy(exchg_data)Join().apply(lp, user_nm, eth_amount, dai_amount)lp.summary()dx = 1x = lp.get_reserve(eth)y = lp.get_reserve(dai)L = lp.get_liquidity()We know from above to maintain price integrity, double-sided change amounts and are determined as such
,
Take RHS of CPT formula and add and to both and to maintain integrity of the price
Perform algebra simular to above and we get the CPT deposit formula
Calculate deposit using derivation
Section titled “Calculate deposit using derivation”dL = dx*L/xdy = y*dL/Lnew_x = (x+dx)new_y = (y+dy)new_L = L+dL
print(f'The updated reserves are {new_x} ETH and {new_y} DAI, and the updated liquidity is {new_L:8f}')Perform deposit using uniswappy
Section titled “Perform deposit using uniswappy”AddLiquidity().apply(lp, eth, user_nm, dx)lp.summary()Single-sided withdraw
Section titled “Single-sided withdraw”dai = ERC20("DAI", "0x111")eth = ERC20("ETH", "0x09")exchg_data = UniswapExchangeData(tkn0 = eth, tkn1 = dai, symbol="LP", address="0x011")
factory = UniswapFactory("ETH pool factory", "0x2")lp = factory.deploy(exchg_data)Join().apply(lp, user_nm, eth_amount, dai_amount)lp.summary()Given and for withdraw
,
Also, given swap equation
A single-sided withdraw constitutes of the sum total of a withdraw and a swap, otherwise known as a WithdrawSwap, and is given by
Plug and into and after performing some algebra we get
Given the fact we know our desired withdraw amount, , we solve the above quadratic to determine our single-sided settlement amount in terms of ; for more detailed information, see this medium article
Perform single-sided withdraw using uniswappy
Section titled “Perform single-sided withdraw using uniswappy”dy = 1amount_out = WithdrawSwap().apply(lp, eth, user_nm, dy)lp.summary()Single-sided deposit
Section titled “Single-sided deposit”dai = ERC20("DAI", "0x111")eth = ERC20("ETH", "0x09")exchg_data = UniswapExchangeData(tkn0 = eth, tkn1 = dai, symbol="LP", address="0x011")
factory = UniswapFactory("ETH pool factory", "0x2")lp = factory.deploy(exchg_data)Join().apply(lp, user_nm, eth_amount, dai_amount)lp.summary()A single-sided deposit constitutes of the sum total of a swap followed by a deposit, otherwise known as a SwapDeposit, and is given by
Given swap equation
Thus, we get this system of equations:
where
To solve for ratio , we plug into , and after some algebra, we get this quadratic
For more detailed information, see this medium article
Perform single-sided deposit using uniswappy
Section titled “Perform single-sided deposit using uniswappy”dy = 1dep = SwapDeposit().apply(lp, eth, user_nm, dy)lp.summary()