diff --git a/sdks/v3-sdk/src/entities/pool.ts b/sdks/v3-sdk/src/entities/pool.ts index 851ce3373..aa51431b4 100644 --- a/sdks/v3-sdk/src/entities/pool.ts +++ b/sdks/v3-sdk/src/entities/pool.ts @@ -2,7 +2,7 @@ import { BigintIsh, CurrencyAmount, Price, Token } from '@uniswap/sdk-core' import JSBI from 'jsbi' import invariant from 'tiny-invariant' import { FACTORY_ADDRESS, FeeAmount, TICK_SPACINGS } from '../constants' -import { NEGATIVE_ONE, Q192 } from '../internalConstants' +import { NEGATIVE_ONE, Q192, ZERO } from '../internalConstants' import { computePoolAddress } from '../utils/computePoolAddress' import { v3Swap } from '../utils/v3swap' import { TickMath } from '../utils/tickMath' @@ -154,11 +154,17 @@ export class Pool { const zeroForOne = inputAmount.currency.equals(this.token0) const { + amountSpecifiedRemaining, amountCalculated: outputAmount, sqrtRatioX96, liquidity, tickCurrent, } = await this.swap(zeroForOne, inputAmount.quotient, sqrtPriceLimitX96) + + if (!JSBI.equal(amountSpecifiedRemaining, ZERO) && !sqrtPriceLimitX96) { + throw new Error('INSUFFICIENT_LIQUIDITY') + } + const outputToken = zeroForOne ? this.token1 : this.token0 return [ CurrencyAmount.fromRawAmount(outputToken, JSBI.multiply(outputAmount, NEGATIVE_ONE)), @@ -181,11 +187,17 @@ export class Pool { const zeroForOne = outputAmount.currency.equals(this.token1) const { + amountSpecifiedRemaining, amountCalculated: inputAmount, sqrtRatioX96, liquidity, tickCurrent, } = await this.swap(zeroForOne, JSBI.multiply(outputAmount.quotient, NEGATIVE_ONE), sqrtPriceLimitX96) + + if (!JSBI.equal(amountSpecifiedRemaining, ZERO) && !sqrtPriceLimitX96) { + throw new Error('INSUFFICIENT_LIQUIDITY') + } + const inputToken = zeroForOne ? this.token0 : this.token1 return [ CurrencyAmount.fromRawAmount(inputToken, inputAmount), @@ -207,7 +219,13 @@ export class Pool { zeroForOne: boolean, amountSpecified: JSBI, sqrtPriceLimitX96?: JSBI - ): Promise<{ amountCalculated: JSBI; sqrtRatioX96: JSBI; liquidity: JSBI; tickCurrent: number }> { + ): Promise<{ + amountSpecifiedRemaining: JSBI + amountCalculated: JSBI + sqrtRatioX96: JSBI + liquidity: JSBI + tickCurrent: number + }> { return v3Swap( JSBI.BigInt(this.fee), this.sqrtRatioX96, diff --git a/sdks/v3-sdk/src/entities/trade.test.ts b/sdks/v3-sdk/src/entities/trade.test.ts index b719903fe..dad5141e1 100644 --- a/sdks/v3-sdk/src/entities/trade.test.ts +++ b/sdks/v3-sdk/src/entities/trade.test.ts @@ -815,20 +815,20 @@ describe('Trade', () => { expect(result[0].swaps[0].route.tokenPath).toEqual([token0, token2]) }) - it.skip('insufficient liquidity', () => { - const result = Trade.bestTradeExactOut( + it('insufficient liquidity', async () => { + const result = await Trade.bestTradeExactOut( [pool_0_1, pool_0_2, pool_1_2], token0, - CurrencyAmount.fromRawAmount(token2, 1200) + CurrencyAmount.fromRawAmount(token2, 120000) ) expect(result).toHaveLength(0) }) - it.skip('insufficient liquidity in one pool but not the other', () => { - const result = Trade.bestTradeExactOut( + it('insufficient liquidity in one pool but not the other', async () => { + const result = await Trade.bestTradeExactOut( [pool_0_1, pool_0_2, pool_1_2], token0, - CurrencyAmount.fromRawAmount(token2, JSBI.BigInt(1050)) + CurrencyAmount.fromRawAmount(token2, JSBI.BigInt(105000)) ) expect(result).toHaveLength(1) }) diff --git a/sdks/v3-sdk/src/entities/trade.ts b/sdks/v3-sdk/src/entities/trade.ts index b2f3677de..e50192ba5 100644 --- a/sdks/v3-sdk/src/entities/trade.ts +++ b/sdks/v3-sdk/src/entities/trade.ts @@ -517,8 +517,8 @@ export class Trade { +): Promise<{ + amountSpecifiedRemaining: JSBI + tickCurrent: number + liquidity: JSBI + sqrtRatioX96: JSBI + amountCalculated: JSBI +}> { if (!sqrtPriceLimitX96) sqrtPriceLimitX96 = zeroForOne ? JSBI.add(TickMath.MIN_SQRT_RATIO, ONE) @@ -119,6 +125,7 @@ export async function v3Swap( } return { + amountSpecifiedRemaining: state.amountSpecifiedRemaining, amountCalculated: state.amountCalculated, sqrtRatioX96: state.sqrtPriceX96, liquidity: state.liquidity,