diff --git a/Frontend/PoolV3Client.cs b/Frontend/PoolV3Client.cs index af1e6a5e6fc7b62afb01bd71f780592404fbf3d3..1bb3b6f9ba2a418249bf5ec10368aa04e01d0c65 100644 --- a/Frontend/PoolV3Client.cs +++ b/Frontend/PoolV3Client.cs @@ -154,7 +154,8 @@ public class PoolV3Client return (uint)_poolFeeTier; } - public async Task<BigInteger> QueryLiquidity(){ + public async Task<BigInteger> QueryLiquidity() + { var handler = _web3.Eth.GetContractQueryHandler<LiquidityFunction>(); var func = new LiquidityFunction(); return await handler.QueryAsync<BigInteger>(_pool.Address, func); @@ -212,28 +213,41 @@ public class PoolV3Client /// </summary> /// <param name="desiredQuote">the ration between token1/token0</param> /// <returns>Quote after the swap</returns> - public async Task<decimal> PerformSwapToCreatDesiredQuote(decimal desiredQuote) + public async Task<decimal> PerformSwapTowardsDesiredQuote(decimal desiredQuote) { - var sqrtPriceX96= await GetSqrtPriceX96(); - var desiredSqrtPriceX96=PriceToSqrtPriceX96((double)desiredQuote); - string[] tokenAddresses=[Token0Address,Token1Address]; - var fromTokenIndex=0; + var sqrtPriceX96 = await GetSqrtPriceX96(); + var desiredSqrtPriceX96 = PriceToSqrtPriceX96((double)desiredQuote); + string[] tokenAddresses = [Token0Address, Token1Address]; + var fromTokenIndex = 0; var amount = 0.0; - var liquidity=await QueryLiquidity(); - if(desiredSqrtPriceX96>sqrtPriceX96){ // we have to by token0 to increase demand and drive the price up - fromTokenIndex=1; // we want to swap from token1 to token0 + var liquidity = await QueryLiquidity(); + var balance = new BigInteger(0); + if (desiredSqrtPriceX96 > sqrtPriceX96) + { // we have to by token0 to increase demand and drive the price up + fromTokenIndex = 1; // we want to swap from token1 to token0 // Taken from getNextSqrtPriceFromAmount1RoundingDown see https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/SqrtPriceMath.sol - amount=(double)(liquidity*(desiredSqrtPriceX96-sqrtPriceX96)); - }else{ // whe have to sell token0 to lower the price - + amount = (double)(liquidity * (desiredSqrtPriceX96 - sqrtPriceX96)) / (double)BigInteger.Pow(2, 96); + balance = await Token1Client.BalanceOf(_account.Address); + } + else + { // whe have to sell token0 to lower the price + // Taken from getNextSqrtPriceFromAmount0ReoundingUp see https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/SqrtPriceMath.sol - amount=(double)(liquidity*(sqrtPriceX96-desiredSqrtPriceX96))/(double)(desiredSqrtPriceX96*sqrtPriceX96); + amount = (double)(liquidity * BigInteger.Pow(2, 96) * (sqrtPriceX96 - desiredSqrtPriceX96)) / (double)(desiredSqrtPriceX96 * sqrtPriceX96); + balance = await Token0Client.BalanceOf(_account.Address); } - amount *= 1+ (int)await QueryPoolFee()/1000.0; // add the fees - - var receipt=await SwapAsync(tokenAddresses[fromTokenIndex],tokenAddresses[(fromTokenIndex+1)%2],Web3.Convert.FromWei(new BigInteger(amount))); - + amount *= 1.0 + (double)await QueryPoolFee() / 1000.0; // add the pool fees + var bigIntAmount = new BigInteger(amount); + + if (balance < bigIntAmount) + { + bigIntAmount = balance; + } + + + var receipt = await SwapAsync(tokenAddresses[fromTokenIndex], tokenAddresses[(fromTokenIndex + 1) % 2], Web3.Convert.FromWei(bigIntAmount)); + return await GetPairRatio(); } diff --git a/Frontend/TokenClient.cs b/Frontend/TokenClient.cs index 61ab43e2171f1df5e98959bc7f8d0d61c1959920..9f2d9b3f82b35e3117dd083fe0c43c01bc377309 100644 --- a/Frontend/TokenClient.cs +++ b/Frontend/TokenClient.cs @@ -109,4 +109,15 @@ public class TokenClient return transactionReceipt.TransactionHash; } + public async Task<BigInteger> BalanceOf(string address){ + var func = new BalanceOfFunction + { + Owner = address, + }; + + var handler = _web3.Eth.GetContractQueryHandler<BalanceOfFunction>(); + return await handler.QueryAsync<BigInteger>(_tokenAddress, func); + + } + }