From 0942009c7cdd5cfa47c31d42a3fd78d11fca3004 Mon Sep 17 00:00:00 2001 From: Alberto Gualis Date: Wed, 15 Jan 2025 17:08:34 +0100 Subject: [PATCH 1/3] feat: activates wethIsEth feature for boosted and nested v3 pools --- packages/lib/modules/pool/actions/LiquidityActionHelpers.ts | 4 ++-- .../pool/actions/add-liquidity/AddLiquidityProvider.tsx | 4 ++-- .../pool/actions/add-liquidity/form/AddLiquidityForm.tsx | 4 ++-- .../handlers/BoostedUnbalancedAddLiquidityV3.handler.ts | 1 + .../add-liquidity/handlers/NestedAddLiquidityV3.handler.ts | 2 ++ .../handlers/ProportionalBoostedAddLiquidityV3.handler.ts | 1 + packages/lib/modules/pool/pool.helpers.ts | 5 +++-- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts b/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts index 1c3b4d130..0a7efaa4f 100644 --- a/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts +++ b/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts @@ -43,7 +43,7 @@ import { isUnbalancedLiquidityDisabled, isV2Pool, isV3Pool, - isV3NotSupportingWethIsEth, + isNotSupportingWethIsEth, getActionableTokenSymbol, hasNestedPools, } from '../pool.helpers' @@ -393,7 +393,7 @@ export function emptyTokenAmounts(pool: Pool): TokenAmount[] { export function shouldShowNativeWrappedSelector(token: ApiToken, pool: Pool) { return ( - !isV3NotSupportingWethIsEth(pool) && // V3 boosted/nested actions don't support wethIsEth currently + !isNotSupportingWethIsEth() && !isCowAmmPool(pool.type) && // Cow AMM pools don't support wethIsEth isNativeOrWrappedNative(token.address as Address, token.chain) ) diff --git a/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx b/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx index b2adfa24d..afd791a45 100644 --- a/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx +++ b/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx @@ -29,7 +29,7 @@ import { useTotalUsdValue } from '@repo/lib/modules/tokens/useTotalUsdValue' import { HumanTokenAmountWithAddress } from '@repo/lib/modules/tokens/token.types' import { isUnhandledAddPriceImpactError } from '@repo/lib/modules/price-impact/price-impact.utils' import { useModalWithPoolRedirect } from '../../useModalWithPoolRedirect' -import { getPoolActionableTokens, isV3NotSupportingWethIsEth } from '../../pool.helpers' +import { getPoolActionableTokens, isNotSupportingWethIsEth } from '../../pool.helpers' import { useUserSettings } from '@repo/lib/modules/user/settings/UserSettingsProvider' import { isUnbalancedAddErrorMessage } from '@repo/lib/shared/utils/error-filters' import { getDefaultProportionalSlippagePercentage } from '@repo/lib/shared/utils/slippage' @@ -207,7 +207,7 @@ export function _useAddLiquidity(urlTxHash?: Hash) { return { transactionSteps, humanAmountsIn, - tokens: wethIsEth && !isV3NotSupportingWethIsEth(pool) ? tokensWithNativeAsset : tokens, + tokens: wethIsEth && !isNotSupportingWethIsEth() ? tokensWithNativeAsset : tokens, validTokens, totalUSDValue, simulationQuery, diff --git a/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx b/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx index 9f1b1fae3..d84501af4 100644 --- a/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx +++ b/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx @@ -55,7 +55,7 @@ import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' import { AddLiquidityFormTabs } from './AddLiquidityFormTabs' import { UnbalancedAddError } from '@repo/lib/shared/components/errors/UnbalancedAddError' import { isUnbalancedAddError } from '@repo/lib/shared/utils/error-filters' -import { isV3NotSupportingWethIsEth } from '../../../pool.helpers' +import { isNotSupportingWethIsEth } from '../../../pool.helpers' import { UnbalancedNestedAddError } from '@repo/lib/shared/components/errors/UnbalancedNestedAddError' import { ApiToken } from '@repo/lib/modules/tokens/token.types' @@ -147,7 +147,7 @@ function AddLiquidityMainForm() { // if native asset balance is higher set that asset as the 'default' useEffect(() => { - if (!isBalancesLoading && nativeAsset && wNativeAsset && !isV3NotSupportingWethIsEth(pool)) { + if (!isBalancesLoading && nativeAsset && wNativeAsset && !isNotSupportingWethIsEth()) { const nativeAssetBalance = balanceFor(nativeAsset.address) const wNativeAssetBalance = balanceFor(wNativeAsset.address) if ( diff --git a/packages/lib/modules/pool/actions/add-liquidity/handlers/BoostedUnbalancedAddLiquidityV3.handler.ts b/packages/lib/modules/pool/actions/add-liquidity/handlers/BoostedUnbalancedAddLiquidityV3.handler.ts index 314bcb7f8..a2d51610e 100644 --- a/packages/lib/modules/pool/actions/add-liquidity/handlers/BoostedUnbalancedAddLiquidityV3.handler.ts +++ b/packages/lib/modules/pool/actions/add-liquidity/handlers/BoostedUnbalancedAddLiquidityV3.handler.ts @@ -62,6 +62,7 @@ export class BoostedUnbalancedAddLiquidityV3Handler extends BaseUnbalancedAddLiq }), protocolVersion: 3, userData: '0x' as Hex, + wethIsEth: this.helpers.isNativeAssetIn(humanAmountsIn), } const { callData, to, value } = permit2 diff --git a/packages/lib/modules/pool/actions/add-liquidity/handlers/NestedAddLiquidityV3.handler.ts b/packages/lib/modules/pool/actions/add-liquidity/handlers/NestedAddLiquidityV3.handler.ts index 482a49025..6830b05e1 100644 --- a/packages/lib/modules/pool/actions/add-liquidity/handlers/NestedAddLiquidityV3.handler.ts +++ b/packages/lib/modules/pool/actions/add-liquidity/handlers/NestedAddLiquidityV3.handler.ts @@ -73,6 +73,7 @@ export class NestedAddLiquidityV3Handler implements AddLiquidityHandler { slippagePercent, queryOutput, permit2, + humanAmountsIn, }: NestedBuildAddLiquidityInputV3): Promise { const addLiquidity = new AddLiquidityNested() @@ -80,6 +81,7 @@ export class NestedAddLiquidityV3Handler implements AddLiquidityHandler { ...queryOutput.sdkQueryOutput, slippage: Slippage.fromPercentage(`${Number(slippagePercent)}`), amountsIn: queryOutput.sdkQueryOutput.amountsIn, + wethIsEth: this.helpers.isNativeAssetIn(humanAmountsIn), } const { callData, to, value } = permit2 diff --git a/packages/lib/modules/pool/actions/add-liquidity/handlers/ProportionalBoostedAddLiquidityV3.handler.ts b/packages/lib/modules/pool/actions/add-liquidity/handlers/ProportionalBoostedAddLiquidityV3.handler.ts index d42bfaab9..a6bc501db 100644 --- a/packages/lib/modules/pool/actions/add-liquidity/handlers/ProportionalBoostedAddLiquidityV3.handler.ts +++ b/packages/lib/modules/pool/actions/add-liquidity/handlers/ProportionalBoostedAddLiquidityV3.handler.ts @@ -69,6 +69,7 @@ export class ProportionalBoostedAddLiquidityV3 implements AddLiquidityHandler { }), protocolVersion: 3, userData: '0x' as Hex, + wethIsEth: this.helpers.isNativeAssetIn(humanAmountsIn), } const { callData, to, value } = permit2 diff --git a/packages/lib/modules/pool/pool.helpers.ts b/packages/lib/modules/pool/pool.helpers.ts index 1f598cf0f..3fe530a9d 100644 --- a/packages/lib/modules/pool/pool.helpers.ts +++ b/packages/lib/modules/pool/pool.helpers.ts @@ -416,8 +416,9 @@ export function isV3WithNestedActionsPool(pool: Pool): boolean { return supportsNestedActions(pool) && isV3Pool(pool) } -export function isV3NotSupportingWethIsEth(pool: Pool): boolean { - return (supportsNestedActions(pool) || isBoosted(pool)) && isV3Pool(pool) +export function isNotSupportingWethIsEth(): boolean { + // Currently all SDK handlers support wethIsEth + return false } export function requiresPermit2Approval(pool: Pool): boolean { From 3234d7f0d1070a93bfdb8a9fbfcd798f445de67a Mon Sep 17 00:00:00 2001 From: Alberto Gualis Date: Wed, 15 Jan 2025 17:27:13 +0100 Subject: [PATCH 2/3] chore: rename function --- .../lib/modules/pool/actions/LiquidityActionHelpers.ts | 8 ++------ .../pool/actions/add-liquidity/AddLiquidityProvider.tsx | 4 ++-- .../pool/actions/add-liquidity/form/AddLiquidityForm.tsx | 4 ++-- packages/lib/modules/pool/pool.helpers.ts | 9 ++++++--- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts b/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts index 0a7efaa4f..03c43d44e 100644 --- a/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts +++ b/packages/lib/modules/pool/actions/LiquidityActionHelpers.ts @@ -43,7 +43,7 @@ import { isUnbalancedLiquidityDisabled, isV2Pool, isV3Pool, - isNotSupportingWethIsEth, + supportsWethIsEth, getActionableTokenSymbol, hasNestedPools, } from '../pool.helpers' @@ -392,11 +392,7 @@ export function emptyTokenAmounts(pool: Pool): TokenAmount[] { } export function shouldShowNativeWrappedSelector(token: ApiToken, pool: Pool) { - return ( - !isNotSupportingWethIsEth() && - !isCowAmmPool(pool.type) && // Cow AMM pools don't support wethIsEth - isNativeOrWrappedNative(token.address as Address, token.chain) - ) + return supportsWethIsEth(pool) && isNativeOrWrappedNative(token.address as Address, token.chain) } export function replaceWrappedWithNativeAsset( diff --git a/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx b/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx index afd791a45..503b4e35c 100644 --- a/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx +++ b/packages/lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx @@ -29,7 +29,7 @@ import { useTotalUsdValue } from '@repo/lib/modules/tokens/useTotalUsdValue' import { HumanTokenAmountWithAddress } from '@repo/lib/modules/tokens/token.types' import { isUnhandledAddPriceImpactError } from '@repo/lib/modules/price-impact/price-impact.utils' import { useModalWithPoolRedirect } from '../../useModalWithPoolRedirect' -import { getPoolActionableTokens, isNotSupportingWethIsEth } from '../../pool.helpers' +import { getPoolActionableTokens, supportsWethIsEth } from '../../pool.helpers' import { useUserSettings } from '@repo/lib/modules/user/settings/UserSettingsProvider' import { isUnbalancedAddErrorMessage } from '@repo/lib/shared/utils/error-filters' import { getDefaultProportionalSlippagePercentage } from '@repo/lib/shared/utils/slippage' @@ -207,7 +207,7 @@ export function _useAddLiquidity(urlTxHash?: Hash) { return { transactionSteps, humanAmountsIn, - tokens: wethIsEth && !isNotSupportingWethIsEth() ? tokensWithNativeAsset : tokens, + tokens: wethIsEth && supportsWethIsEth(pool) ? tokensWithNativeAsset : tokens, validTokens, totalUSDValue, simulationQuery, diff --git a/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx b/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx index d84501af4..aed6bf831 100644 --- a/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx +++ b/packages/lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx @@ -55,7 +55,7 @@ import { useTokens } from '@repo/lib/modules/tokens/TokensProvider' import { AddLiquidityFormTabs } from './AddLiquidityFormTabs' import { UnbalancedAddError } from '@repo/lib/shared/components/errors/UnbalancedAddError' import { isUnbalancedAddError } from '@repo/lib/shared/utils/error-filters' -import { isNotSupportingWethIsEth } from '../../../pool.helpers' +import { supportsWethIsEth } from '../../../pool.helpers' import { UnbalancedNestedAddError } from '@repo/lib/shared/components/errors/UnbalancedNestedAddError' import { ApiToken } from '@repo/lib/modules/tokens/token.types' @@ -147,7 +147,7 @@ function AddLiquidityMainForm() { // if native asset balance is higher set that asset as the 'default' useEffect(() => { - if (!isBalancesLoading && nativeAsset && wNativeAsset && !isNotSupportingWethIsEth()) { + if (!isBalancesLoading && nativeAsset && wNativeAsset && supportsWethIsEth(pool)) { const nativeAssetBalance = balanceFor(nativeAsset.address) const wNativeAssetBalance = balanceFor(wNativeAsset.address) if ( diff --git a/packages/lib/modules/pool/pool.helpers.ts b/packages/lib/modules/pool/pool.helpers.ts index 3fe530a9d..14917f658 100644 --- a/packages/lib/modules/pool/pool.helpers.ts +++ b/packages/lib/modules/pool/pool.helpers.ts @@ -416,9 +416,12 @@ export function isV3WithNestedActionsPool(pool: Pool): boolean { return supportsNestedActions(pool) && isV3Pool(pool) } -export function isNotSupportingWethIsEth(): boolean { - // Currently all SDK handlers support wethIsEth - return false +export function supportsWethIsEth(pool: Pool): boolean { + /* + Currently all SDK handlers support wethIsEth + and Cow AMM pools is the only scenario that doesn't support wethIsEth + */ + return !isCowAmmPool(pool.type) } export function requiresPermit2Approval(pool: Pool): boolean { From 230b993eaefb7020598aac0128fe42a8d4d7da97 Mon Sep 17 00:00:00 2001 From: Alberto Gualis Date: Wed, 15 Jan 2025 19:15:30 +0100 Subject: [PATCH 3/3] fix: permit 2 approvals for wethIsEth --- .../approvals/permit2/permit2.helpers.ts | 35 +++++++-------- .../approvals/permit2/usePermit2Allowance.tsx | 43 +++++++++---------- .../transaction-steps/useSignPermit2Step.tsx | 16 ++++--- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/packages/lib/modules/tokens/approvals/permit2/permit2.helpers.ts b/packages/lib/modules/tokens/approvals/permit2/permit2.helpers.ts index 33145c072..5d7f1970a 100644 --- a/packages/lib/modules/tokens/approvals/permit2/permit2.helpers.ts +++ b/packages/lib/modules/tokens/approvals/permit2/permit2.helpers.ts @@ -5,7 +5,7 @@ import { GetTokenFn } from '../../TokensProvider' import { AllowedAmountsByTokenAddress, ExpirationByTokenAddress } from './usePermit2Allowance' import { TokenAmountIn } from './useSignPermit2' import { GqlChain } from '@repo/lib/shared/services/api/generated/graphql' -import { isWrappedNativeAsset } from '../../token.helpers' +import { isNativeAsset, isWrappedNativeAsset } from '../../token.helpers' export function hasValidPermit2( tokenAmountsIn?: TokenAmountIn[], @@ -51,7 +51,7 @@ export function getTokenSymbolsForPermit2({ if (!tokenAmountsIn) return [] const chain = getGqlChain(chainId) - const tokenSymbols = filterWrappedNativeAsset({ + const tokenSymbols = filterTokensForPermit2({ wethIsEth, tokenAmountsIn, chain, @@ -65,18 +65,9 @@ export function getTokenSymbolsForPermit2({ } // Returns the token addresses that need to be approved for permit2 -export function getTokenAddressesForPermit2({ - wethIsEth, - tokenAmountsIn, - chainId, -}: BasePermit2Params): Address[] | undefined { - if (!tokenAmountsIn) return undefined - const chain = getGqlChain(chainId) - return filterWrappedNativeAsset({ - wethIsEth, - chain, - tokenAmountsIn, - }).map(t => t.address) +export function getTokenAddressesForPermit2(tokenAmountsIn?: TokenAmountIn[]): Address[] { + if (!tokenAmountsIn) return [] + return tokenAmountsIn.map(t => t.address) } export function permit2Address(chain: GqlChain): Address { @@ -84,7 +75,12 @@ export function permit2Address(chain: GqlChain): Address { return getNetworkConfig(chain).contracts.permit2 || ('' as Address) } -function filterWrappedNativeAsset({ +/* + Returns the token amounts that need to be approved for permit2 + Excludes the native asset + If wethIsEth, it excludes the wrapped native asset (as the user will use the native asset instead, which does not require approval) +*/ +export function filterTokensForPermit2({ tokenAmountsIn, wethIsEth, chain, @@ -94,6 +90,11 @@ function filterWrappedNativeAsset({ chain: GqlChain }): TokenAmountIn[] { if (!tokenAmountsIn) return [] - if (!wethIsEth) return tokenAmountsIn - return tokenAmountsIn.filter(t => !isWrappedNativeAsset(t.address, chain)) + return ( + tokenAmountsIn + // native asset does not require permit2 approval + .filter(t => !isNativeAsset(t.address, chain)) + // if wethIsEth the wrapped native asset token will be replaced with the native asset token so no required permit2 approval neither + .filter(t => wethIsEth && !isWrappedNativeAsset(t.address, chain)) + ) } diff --git a/packages/lib/modules/tokens/approvals/permit2/usePermit2Allowance.tsx b/packages/lib/modules/tokens/approvals/permit2/usePermit2Allowance.tsx index d245ebc8c..4c56e236a 100644 --- a/packages/lib/modules/tokens/approvals/permit2/usePermit2Allowance.tsx +++ b/packages/lib/modules/tokens/approvals/permit2/usePermit2Allowance.tsx @@ -13,7 +13,7 @@ export type Permit2AllowanceResult = ReturnType type Params = { chainId: number - tokenAddresses?: Address[] + tokenAddresses: Address[] owner?: Address enabled: boolean spender: Address @@ -37,33 +37,30 @@ export function usePermit2Allowance({ chainId, tokenAddresses, owner, enabled, s contracts, allowFailure: false, query: { - enabled: enabled && tokenAddresses && tokenAddresses.length > 0 && !!owner && !!spender, + enabled: enabled && tokenAddresses.length > 0 && !!owner && !!spender, }, }) - const nonces: NoncesByTokenAddress | undefined = - tokenAddresses && data - ? zipObject( - tokenAddresses, - data.map(result => result[2]) - ) - : undefined + const nonces: NoncesByTokenAddress | undefined = data + ? zipObject( + tokenAddresses, + data.map(result => result[2]) + ) + : undefined - const expirations: ExpirationByTokenAddress | undefined = - tokenAddresses && data - ? zipObject( - tokenAddresses, - data.map(result => result[1]) - ) - : undefined + const expirations: ExpirationByTokenAddress | undefined = data + ? zipObject( + tokenAddresses, + data.map(result => result[1]) + ) + : undefined - const allowedAmounts: AllowedAmountsByTokenAddress | undefined = - tokenAddresses && data - ? zipObject( - tokenAddresses, - data.map(result => result[0]) - ) - : undefined + const allowedAmounts: AllowedAmountsByTokenAddress | undefined = data + ? zipObject( + tokenAddresses, + data.map(result => result[0]) + ) + : undefined return { isLoadingPermit2Allowances: isLoading, diff --git a/packages/lib/modules/transactions/transaction-steps/useSignPermit2Step.tsx b/packages/lib/modules/transactions/transaction-steps/useSignPermit2Step.tsx index 9b558a431..ac7681774 100644 --- a/packages/lib/modules/transactions/transaction-steps/useSignPermit2Step.tsx +++ b/packages/lib/modules/transactions/transaction-steps/useSignPermit2Step.tsx @@ -8,6 +8,7 @@ import { useMemo } from 'react' import { useTokens } from '../../tokens/TokensProvider' import { + filterTokensForPermit2, getTokenAddressesForPermit2, getTokenSymbolsForPermit2, hasValidPermit2, @@ -18,6 +19,7 @@ import { SignatureState } from '../../web3/signatures/signature.helpers' import { NetworkSwitchButton, useChainSwitch } from '../../web3/useChainSwitch' import { StepDetails, TransactionStep } from './lib' import { LabelWithIcon } from '@repo/lib/shared/components/btns/button-group/LabelWithIcon' +import { getGqlChain } from '@repo/lib/config/app.config' /* Returns a transaction step to sign a permit2 for the token amounts in @@ -31,17 +33,19 @@ export function useSignPermit2Step(params: BasePermit2Params): TransactionStep | const { isLoadingPermit2Allowances, nonces, expirations, allowedAmounts } = usePermit2Allowance({ chainId, - tokenAddresses: getTokenAddressesForPermit2({ - chainId, - tokenAmountsIn, - wethIsEth, - }), + tokenAddresses: getTokenAddressesForPermit2(tokenAmountsIn), owner: userAddress, enabled: isPermit2 && !!spender, spender: spender, }) - const isValidPermit2 = hasValidPermit2(tokenAmountsIn, expirations, allowedAmounts) + const filteredTokenAmountsIn = filterTokensForPermit2({ + chain: getGqlChain(chainId), + wethIsEth, + tokenAmountsIn, + }) + + const isValidPermit2 = hasValidPermit2(filteredTokenAmountsIn, expirations, allowedAmounts) const { signPermit2,