From a7e8f643c53e377087fc72b42259ab51cb4df2ca Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Thu, 19 Dec 2024 12:02:45 +0000 Subject: [PATCH] fix(TS): Check for supportsUnbalancedLiquidity in pool state for unbalanced operations. --- typescript/src/vault/types.ts | 1 + typescript/src/vault/vault.ts | 10 ++++++++++ typescript/test/customPool.test.ts | 9 +++++++++ typescript/test/hooks/afterAddLiquidity.test.ts | 1 + typescript/test/hooks/afterRemoveLiquidity.test.ts | 1 + typescript/test/hooks/afterSwap.test.ts | 9 +++++++++ typescript/test/hooks/beforeAddLiquidity.test.ts | 1 + typescript/test/hooks/beforeRemoveLiquidity.test.ts | 1 + typescript/test/hooks/beforeSwap.test.ts | 1 + typescript/test/hooks/directionalFee.test.ts | 2 ++ typescript/test/hooks/exitFee.test.ts | 1 + typescript/test/hooks/hook.test.ts | 9 +++++++++ typescript/test/hooks/stableSurge.test.ts | 1 + typescript/test/utils/readTestData.ts | 8 ++++++++ 14 files changed, 55 insertions(+) diff --git a/typescript/src/vault/types.ts b/typescript/src/vault/types.ts index 789e3d7..7d9b1f9 100644 --- a/typescript/src/vault/types.ts +++ b/typescript/src/vault/types.ts @@ -14,6 +14,7 @@ export type BasePoolState = { swapFee: bigint; aggregateSwapFee: bigint; totalSupply: bigint; + supportsUnbalancedLiquidity: boolean; hookType?: string; }; diff --git a/typescript/src/vault/vault.ts b/typescript/src/vault/vault.ts index b71bfa5..c97f4f6 100644 --- a/typescript/src/vault/vault.ts +++ b/typescript/src/vault/vault.ts @@ -386,6 +386,7 @@ export class Vault { let swapFeeAmountsScaled18: bigint[]; if (addLiquidityInput.kind === AddKind.UNBALANCED) { + this._requireUnbalancedLiquidityEnabled(poolState); amountsInScaled18 = maxAmountsInScaled18; const computed = computeAddLiquidityUnbalanced( updatedBalancesLiveScaled18, @@ -399,6 +400,7 @@ export class Vault { bptAmountOut = computed.bptAmountOut; swapFeeAmountsScaled18 = computed.swapFeeAmounts; } else if (addLiquidityInput.kind === AddKind.SINGLE_TOKEN_EXACT_OUT) { + this._requireUnbalancedLiquidityEnabled(poolState); const tokenIndex = this._getSingleInputIndex(maxAmountsInScaled18); amountsInScaled18 = maxAmountsInScaled18; bptAmountOut = addLiquidityInput.minBptAmountOutRaw; @@ -557,6 +559,7 @@ export class Vault { } else if ( removeLiquidityInput.kind === RemoveKind.SINGLE_TOKEN_EXACT_IN ) { + this._requireUnbalancedLiquidityEnabled(poolState); bptAmountIn = removeLiquidityInput.maxBptAmountInRaw; amountsOutScaled18 = minAmountsOutScaled18; tokenOutIndex = this._getSingleInputIndex( @@ -581,6 +584,7 @@ export class Vault { } else if ( removeLiquidityInput.kind === RemoveKind.SINGLE_TOKEN_EXACT_OUT ) { + this._requireUnbalancedLiquidityEnabled(poolState); amountsOutScaled18 = minAmountsOutScaled18; tokenOutIndex = this._getSingleInputIndex( removeLiquidityInput.minAmountsOutRaw, @@ -780,4 +784,10 @@ export class Vault { } return true; } + + private _requireUnbalancedLiquidityEnabled(poolState: PoolState): void { + if (!poolState.supportsUnbalancedLiquidity) { + throw new Error('DoesNotSupportUnbalancedLiquidity'); + } + } } diff --git a/typescript/test/customPool.test.ts b/typescript/test/customPool.test.ts index 9ecdeba..e136025 100644 --- a/typescript/test/customPool.test.ts +++ b/typescript/test/customPool.test.ts @@ -27,6 +27,7 @@ describe('custom pool tests', () => { totalSupply: 1736721048412749353n, randoms: [7000000000000000000n, 8000000000000000000n], aggregateSwapFee: 0n, + supportsUnbalancedLiquidity: true, }; const calculatedAmount = vault.swap( @@ -49,6 +50,14 @@ class CustomPool implements PoolBase { this.randoms = poolState.randoms; } + getMaximumInvariantRatio(): bigint { + return 1n; + } + + getMinimumInvariantRatio(): bigint { + return 1n; + } + getMaxSwapAmount(): bigint { return 1n; } diff --git a/typescript/test/hooks/afterAddLiquidity.test.ts b/typescript/test/hooks/afterAddLiquidity.test.ts index 52b7ff0..1b2e876 100644 --- a/typescript/test/hooks/afterAddLiquidity.test.ts +++ b/typescript/test/hooks/afterAddLiquidity.test.ts @@ -29,6 +29,7 @@ const pool = { balancesLiveScaled18: [1000000000000000000n, 1000000000000000000n], tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 1000000000000000000n, + supportsUnbalancedLiquidity: true, }; describe('hook - afterAddLiquidity', () => { diff --git a/typescript/test/hooks/afterRemoveLiquidity.test.ts b/typescript/test/hooks/afterRemoveLiquidity.test.ts index 366a263..8b0bf82 100644 --- a/typescript/test/hooks/afterRemoveLiquidity.test.ts +++ b/typescript/test/hooks/afterRemoveLiquidity.test.ts @@ -35,6 +35,7 @@ const pool = { balancesLiveScaled18: [1000000000000000000n, 1000000000000000000n], tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 1000000000000000000n, + supportsUnbalancedLiquidity: true, }; describe('hook - afterRemoveLiquidity', () => { diff --git a/typescript/test/hooks/afterSwap.test.ts b/typescript/test/hooks/afterSwap.test.ts index 7b5e5c4..5178502 100644 --- a/typescript/test/hooks/afterSwap.test.ts +++ b/typescript/test/hooks/afterSwap.test.ts @@ -20,6 +20,7 @@ const pool = { balancesLiveScaled18: [1000000000000000000n, 1000000000000000000n], tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 1000000000000000000n, + supportsUnbalancedLiquidity: true, }; const swapInput = { @@ -87,6 +88,14 @@ describe('hook - afterSwap', () => { class CustomPool implements PoolBase { constructor() {} + getMaximumInvariantRatio(): bigint { + return 1n; + } + + getMinimumInvariantRatio(): bigint { + return 1n; + } + getMaxSwapAmount(): bigint { return 1n; } diff --git a/typescript/test/hooks/beforeAddLiquidity.test.ts b/typescript/test/hooks/beforeAddLiquidity.test.ts index d0290d8..ed3ff0c 100644 --- a/typescript/test/hooks/beforeAddLiquidity.test.ts +++ b/typescript/test/hooks/beforeAddLiquidity.test.ts @@ -29,6 +29,7 @@ const pool = { balancesLiveScaled18: [2000000000000000000n, 2000000000000000000n], tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 1000000000000000000n, + supportsUnbalancedLiquidity: true, }; describe('hook - beforeAddLiquidity', () => { diff --git a/typescript/test/hooks/beforeRemoveLiquidity.test.ts b/typescript/test/hooks/beforeRemoveLiquidity.test.ts index 7c075ee..3d184a8 100644 --- a/typescript/test/hooks/beforeRemoveLiquidity.test.ts +++ b/typescript/test/hooks/beforeRemoveLiquidity.test.ts @@ -35,6 +35,7 @@ const pool = { balancesLiveScaled18: [2000000000000000000n, 2000000000000000000n], tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 1000000000000000000n, + supportsUnbalancedLiquidity: true, }; describe('hook - afterRemoveLiquidity', () => { diff --git a/typescript/test/hooks/beforeSwap.test.ts b/typescript/test/hooks/beforeSwap.test.ts index e0fabf0..f5bd570 100644 --- a/typescript/test/hooks/beforeSwap.test.ts +++ b/typescript/test/hooks/beforeSwap.test.ts @@ -20,6 +20,7 @@ const pool = { balancesLiveScaled18: [2000000000000000000n, 2000000000000000000n], tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 1000000000000000000n, + supportsUnbalancedLiquidity: true, }; const swapInput = { diff --git a/typescript/test/hooks/directionalFee.test.ts b/typescript/test/hooks/directionalFee.test.ts index e6da718..cc996c1 100644 --- a/typescript/test/hooks/directionalFee.test.ts +++ b/typescript/test/hooks/directionalFee.test.ts @@ -38,6 +38,7 @@ const stablePoolStateWithHook: StableState = { aggregateSwapFee: 0n, totalSupply: totalSupply, amp: 1000000n, + supportsUnbalancedLiquidity: true, }; const stablePoolStateWithoutHook: StableState = { @@ -51,6 +52,7 @@ const stablePoolStateWithoutHook: StableState = { aggregateSwapFee: 0n, totalSupply: totalSupply, amp: 1000000n, + supportsUnbalancedLiquidity: true, }; const swapInput: SwapInput = { diff --git a/typescript/test/hooks/exitFee.test.ts b/typescript/test/hooks/exitFee.test.ts index 484b7b1..1ac5c97 100644 --- a/typescript/test/hooks/exitFee.test.ts +++ b/typescript/test/hooks/exitFee.test.ts @@ -19,6 +19,7 @@ const poolState = { balancesLiveScaled18: [5000000000000000n, 5000000000000000000n], tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 158113883008415798n, + supportsUnbalancedLiquidity: true, }; const removeLiquidityInput = { diff --git a/typescript/test/hooks/hook.test.ts b/typescript/test/hooks/hook.test.ts index 3d232f7..11a7254 100644 --- a/typescript/test/hooks/hook.test.ts +++ b/typescript/test/hooks/hook.test.ts @@ -31,6 +31,7 @@ describe('hook tests', () => { totalSupply: 1736721048412749353n, randoms: [77n, 88n], aggregateSwapFee: 0n, + supportsUnbalancedLiquidity: true, }; test('should throw when no hook state passed', () => { expect(() => { @@ -67,6 +68,14 @@ class CustomPool implements PoolBase { this.randoms = poolState.randoms; } + getMaximumInvariantRatio(): bigint { + return 1n; + } + + getMinimumInvariantRatio(): bigint { + return 1n; + } + getMaxSwapAmount(): bigint { return 1n; } diff --git a/typescript/test/hooks/stableSurge.test.ts b/typescript/test/hooks/stableSurge.test.ts index 5d5b6e2..573bc05 100644 --- a/typescript/test/hooks/stableSurge.test.ts +++ b/typescript/test/hooks/stableSurge.test.ts @@ -19,6 +19,7 @@ const poolState: StableState = { tokenRates: [1000000000000000000n, 1000000000000000000n], totalSupply: 100000000000000000000000n, amp: 1000000n, + supportsUnbalancedLiquidity: true, }; const hookState: HookStateStableSurge = { diff --git a/typescript/test/utils/readTestData.ts b/typescript/test/utils/readTestData.ts index 50d9e76..675374e 100644 --- a/typescript/test/utils/readTestData.ts +++ b/typescript/test/utils/readTestData.ts @@ -152,6 +152,10 @@ function mapPool( pool as TransformBigintToString ).weights.map((w) => BigInt(w)), aggregateSwapFee: BigInt(pool.aggregateSwapFee ?? '0'), + supportsUnbalancedLiquidity: + pool.supportsUnbalancedLiquidity === undefined + ? true + : pool.supportsUnbalancedLiquidity, }; } if (pool.poolType === 'STABLE') { @@ -166,6 +170,10 @@ function mapPool( totalSupply: BigInt(pool.totalSupply), amp: BigInt((pool as TransformBigintToString).amp), aggregateSwapFee: BigInt(pool.aggregateSwapFee ?? '0'), + supportsUnbalancedLiquidity: + pool.supportsUnbalancedLiquidity === undefined + ? true + : pool.supportsUnbalancedLiquidity, }; } if (pool.poolType === 'Buffer') {