Getter method for the amount of coin[i] tokens to input for swapping out dy amount of coin[j]
Returns: dx (uint256).
Input
Type
Description
i
uint256
Index of input token (check pool.coins(i) to get coin address at i-th index)
j
uint256
Index of output token
dy
uint256
amount of input coin[j] tokens received
swap
address
Pool contract address
Note
This is an approximate method, and returns estimates close to the input amount. Expensive to call on-chain.
Source code
@view@externaldefget_dx(i:uint256,j:uint256,dy:uint256,swap:address)->uint256:dx:uint256=0xp:uint256[N_COINS]=empty(uint256[N_COINS])fee_dy:uint256=0_dy:uint256=dy# for more precise dx (but never exact), increase num loopsforkinrange(5):dx,xp=self._get_dx_fee(i,j,_dy,swap)fee_dy=Curve(swap).fee_calc(xp)*_dy/10**10_dy=dy+fee_dy+1returndx
Getter method for the output tokens (including fees) when withdrawing one coin.
Returns: amount of output tokens (uint256).
Input
Type
Description
token_amount
uint256
LP token amount
i
uint256
Index of the token to withdraw
swap
address
Pool contract address
Source code
@view@externaldefcalc_withdraw_one_coin(token_amount:uint256,i:uint256,swap:address)->uint256:returnself._calc_withdraw_one_coin(token_amount,i,swap)[0]@internal@viewdef_calc_withdraw_one_coin(token_amount:uint256,i:uint256,swap:address)->(uint256,uint256):token_supply:uint256=Curve(swap).totalSupply()asserttoken_amount<=token_supply# dev: token amount more than supplyasserti<N_COINS# dev: coin out of rangemath:Math=Curve(swap).MATH()xx:uint256[N_COINS]=empty(uint256[N_COINS])price_scale:uint256[N_COINS-1]=empty(uint256[N_COINS-1])forkinrange(N_COINS):xx[k]=Curve(swap).balances(k)ifk>0:price_scale[k-1]=Curve(swap).price_scale(k-1)precisions:uint256[N_COINS]=Curve(swap).precisions()A:uint256=Curve(swap).A()gamma:uint256=Curve(swap).gamma()xp:uint256[N_COINS]=precisionsD0:uint256=0p:uint256=0price_scale_i:uint256=PRECISION*precisions[0]xp[0]*=xx[0]forkinrange(1,N_COINS):p=price_scale[k-1]ifi==k:price_scale_i=p*xp[i]xp[k]=xp[k]*xx[k]*p/PRECISIONifCurve(swap).future_A_gamma_time()>block.timestamp:D0=math.newton_D(A,gamma,xp,0)else:D0=Curve(swap).D()D:uint256=D0fee:uint256=self._fee(xp,swap)dD:uint256=token_amount*D/token_supplyD_fee:uint256=fee*dD/(2*10**10)+1approx_fee:uint256=N_COINS*D_fee*xx[i]/DD-=(dD-D_fee)y_out:uint256[2]=math.get_y(A,gamma,xp,D,i)dy:uint256=(xp[i]-y_out[0])*PRECISION/price_scale_ixp[i]=y_out[0]returndy,approx_fee
Index of input token (check pool.coins(i) to get coin address at i-th index)
j
uint256
Index of output token
dx
uint256
Amount of input coin[i] tokens
swap
address
Pool contract address
Source code
@external@viewdefcalc_fee_get_dy(i:uint256,j:uint256,dx:uint256,swap:address)->uint256:dy:uint256=0xp:uint256[N_COINS]=empty(uint256[N_COINS])dy,xp=self._get_dy_nofee(i,j,dx,swap)returnCurve(swap).fee_calc(xp)*dy/10**10@internal@viewdef_get_dy_nofee(i:uint256,j:uint256,dx:uint256,swap:address)->(uint256,uint256[N_COINS]):asserti!=jandi<N_COINSandj<N_COINS,"coin index out of range"assertdx>0,"do not exchange 0 coins"math:Math=Curve(swap).MATH()xp:uint256[N_COINS]=empty(uint256[N_COINS])precisions:uint256[N_COINS]=empty(uint256[N_COINS])price_scale:uint256[N_COINS-1]=empty(uint256[N_COINS-1])D:uint256=0token_supply:uint256=0A:uint256=0gamma:uint256=0xp,D,token_supply,price_scale,A,gamma,precisions=self._prep_calc(swap)# adjust xp with input dxxp[i]+=dxxp[0]*=precisions[0]forkinrange(N_COINS-1):xp[k+1]=xp[k+1]*price_scale[k]*precisions[k+1]/PRECISIONy_out:uint256[2]=math.get_y(A,gamma,xp,D,j)dy:uint256=xp[j]-y_out[0]-1xp[j]=y_out[0]ifj>0:dy=dy*PRECISION/price_scale[j-1]dy/=precisions[j]returndy,xp
Function to calculate the fees for withdraw_one_coin.
Returns: fee (uint256).
Input
Type
Description
token_amount
uint256
LP token amount
i
uint256
Index of the token to withdraw
swap
address
Pool contract address
Source code
@external@viewdefcalc_fee_withdraw_one_coin(token_amount:uint256,i:uint256,swap:address)->uint256:returnself._calc_withdraw_one_coin(token_amount,i,swap)[1]@internal@viewdef_calc_withdraw_one_coin(token_amount:uint256,i:uint256,swap:address)->(uint256,uint256):token_supply:uint256=Curve(swap).totalSupply()asserttoken_amount<=token_supply# dev: token amount more than supplyasserti<N_COINS# dev: coin out of rangemath:Math=Curve(swap).MATH()xx:uint256[N_COINS]=empty(uint256[N_COINS])price_scale:uint256[N_COINS-1]=empty(uint256[N_COINS-1])forkinrange(N_COINS):xx[k]=Curve(swap).balances(k)ifk>0:price_scale[k-1]=Curve(swap).price_scale(k-1)precisions:uint256[N_COINS]=Curve(swap).precisions()A:uint256=Curve(swap).A()gamma:uint256=Curve(swap).gamma()xp:uint256[N_COINS]=precisionsD0:uint256=0p:uint256=0price_scale_i:uint256=PRECISION*precisions[0]xp[0]*=xx[0]forkinrange(1,N_COINS):p=price_scale[k-1]ifi==k:price_scale_i=p*xp[i]xp[k]=xp[k]*xx[k]*p/PRECISIONifCurve(swap).future_A_gamma_time()>block.timestamp:D0=math.newton_D(A,gamma,xp,0)else:D0=Curve(swap).D()D:uint256=D0fee:uint256=self._fee(xp,swap)dD:uint256=token_amount*D/token_supplyD_fee:uint256=fee*dD/(2*10**10)+1approx_fee:uint256=N_COINS*D_fee*xx[i]/DD-=(dD-D_fee)y_out:uint256[2]=math.get_y(A,gamma,xp,D,i)dy:uint256=(xp[i]-y_out[0])*PRECISION/price_scale_ixp[i]=y_out[0]returndy,approx_fee