From d89c354b553377ed67a4324ef9397ce9629ead04 Mon Sep 17 00:00:00 2001 From: Alberto Gualis Date: Mon, 7 Oct 2024 13:29:53 +0200 Subject: [PATCH] fix: USDT approval edge case --- app/(app)/debug/page.tsx | 90 ++--------------- app/(app)/debug/pools/page.tsx | 99 +++++++++++++++++++ .../debug/revoke-relayer-approval/page.tsx | 49 +++++++++ .../approvals/useTokenApprovalSteps.tsx | 19 +++- 4 files changed, 169 insertions(+), 88 deletions(-) create mode 100644 app/(app)/debug/pools/page.tsx create mode 100644 app/(app)/debug/revoke-relayer-approval/page.tsx diff --git a/app/(app)/debug/page.tsx b/app/(app)/debug/page.tsx index 2a9d617d1..b1381836a 100644 --- a/app/(app)/debug/page.tsx +++ b/app/(app)/debug/page.tsx @@ -9,89 +9,8 @@ export default function Debug() { Demos - - Sepolia V3 pool (Balancer 50 BAL 50 WETH) - - - Add liquidity in WEIGHTED (wjAura-weth) - - - Add liquidity in META_STABLE (wstETH_wETH) - - - Add liquidity in STABLE (B-rETH-STABLE in Mainnet) - - - Add liquidity in STABLE with BPT tokens (AuraBal 80/20 pool in Mainnet) - - - Add liquidity in STABLE (FRAX_USDC_MAI in Optimism) - - - Add liquidity in nested pool (50WETH-50-3pool) - - - Add liquidity in Gyro pool (2CLP-WSTETH-WETH in Mainnet) - - - Add liquidity in Gyro pool (2CLP_WMATIC/MATICX in Polygon) - - - Weighted Pool in recovery mode (not paused) - - - Composable Pool in recovery mode (not paused) - - - Pool with Merkl APR items (Fraxtal) - - - CoW AMM Pool (Sepolia) - - - Bricked Composable Stable Pool in recovery mode and paused - - - Old boosted pool with issues + + Pools Token select @@ -112,7 +31,10 @@ export default function Debug() { Modal animation - Remove allowance + Remove token allowance + + + Revoke relayer approval diff --git a/app/(app)/debug/pools/page.tsx b/app/(app)/debug/pools/page.tsx new file mode 100644 index 000000000..4b0bf74a8 --- /dev/null +++ b/app/(app)/debug/pools/page.tsx @@ -0,0 +1,99 @@ +'use client' +import { Heading, VStack } from '@chakra-ui/react' +import NextLink from 'next/link' +import { Link } from '@chakra-ui/react' +import FadeInOnView from '@/lib/shared/components/containers/FadeInOnView' + +export default function DebugPools() { + return ( + + + Debug pools + + Sepolia V3 pool (Balancer 50 BAL 50 WETH) + + + Add liquidity in WEIGHTED (wjAura-weth) + + + Add liquidity in META_STABLE (wstETH_wETH) + + + Add liquidity in STABLE (B-rETH-STABLE in Mainnet) + + + Add liquidity in STABLE with BPT tokens (AuraBal 80/20 pool in Mainnet) + + + Add liquidity in STABLE (FRAX_USDC_MAI in Optimism) + + + Add liquidity in nested pool (50WETH-50-3pool) + + + Add liquidity in Gyro pool (2CLP-WSTETH-WETH in Mainnet) + + + Add liquidity in Gyro pool (2CLP_WMATIC/MATICX in Polygon) + + + Weighted Pool in recovery mode (not paused) + + + Composable Pool in recovery mode (not paused) + + + Pool with Merkl APR items (Fraxtal) + + + CoW AMM Pool (Sepolia) + + + Bricked Composable Stable Pool in recovery mode and paused + + + Old boosted pool with issues + + + + ) +} diff --git a/app/(app)/debug/revoke-relayer-approval/page.tsx b/app/(app)/debug/revoke-relayer-approval/page.tsx new file mode 100644 index 000000000..15f51f3c9 --- /dev/null +++ b/app/(app)/debug/revoke-relayer-approval/page.tsx @@ -0,0 +1,49 @@ +'use client' + +import { getNetworkConfig } from '@/lib/config/app.config' +import { TransactionStepButton } from '@/lib/modules/transactions/transaction-steps/TransactionStepButton' +import { TransactionLabels } from '@/lib/modules/transactions/transaction-steps/lib' +import { useUserAccount } from '@/lib/modules/web3/UserAccountProvider' +import { + ManagedTransactionInput, + useManagedTransaction, +} from '@/lib/modules/web3/contracts/useManagedTransaction' +import { Center, VStack } from '@chakra-ui/react' + +export default function Page() { + const labels: TransactionLabels = { + title: 'Revoke relayer approval', + description: 'Revoke Balancer relayer approval', + init: 'Revoke relayer approval', + confirming: 'Confirming relayer approval revoke...', + confirmed: 'Relayer revoked!', + tooltip: '', + } + const { chain, userAddress } = useUserAccount() + const chainId = chain?.id || 1 + const config = getNetworkConfig(chainId) + + const relayerAddress = config.contracts.balancer.relayerV6 + const vaultAddress = config.contracts.balancer.vaultV2 + + const props: ManagedTransactionInput = { + contractAddress: vaultAddress, + contractId: 'balancer.vaultV2', + functionName: 'setRelayerApproval', + labels, + chainId, + args: [userAddress, relayerAddress, false], + enabled: !!userAddress, + txSimulationMeta: {}, + } + + const transaction = useManagedTransaction(props) + + return ( +
+ + + +
+ ) +} diff --git a/lib/modules/tokens/approvals/useTokenApprovalSteps.tsx b/lib/modules/tokens/approvals/useTokenApprovalSteps.tsx index 0bf7eb358..4e133e9ef 100644 --- a/lib/modules/tokens/approvals/useTokenApprovalSteps.tsx +++ b/lib/modules/tokens/approvals/useTokenApprovalSteps.tsx @@ -64,17 +64,28 @@ export function useTokenApprovalSteps({ }) const steps = useMemo(() => { - return tokenAmountsToApprove.map(tokenAmountToApprove => { + return tokenAmountsToApprove.map((tokenAmountToApprove, index) => { const { tokenAddress, requiredRawAmount, requestedRawAmount } = tokenAmountToApprove + // USDT edge-case: requires setting approval to 0n before adjusting the value up again + const isApprovingZeroForDoubleApproval = + requiresDoubleApproval(chain, tokenAddress) && requiredRawAmount === 0n + const id = isApprovingZeroForDoubleApproval ? `${tokenAddress}-0` : tokenAddress const token = getToken(tokenAddress, chain) const symbol = bptSymbol ?? (token && token?.symbol) ?? 'Unknown' const labels = buildTokenApprovalLabels({ actionType, symbol }) - const id = tokenAddress const isComplete = () => { const isAllowed = tokenAllowances.allowanceFor(tokenAddress) >= requiredRawAmount - // USDT edge-case: requires setting approval to 0n before adjusting the value up again - if (requiresDoubleApproval(chain, tokenAddress)) return isAllowed + if (isApprovingZeroForDoubleApproval) { + // Edge case USDT case is completed if: + // - The allowance is 0n + // - The allowance is greater than the required amount (of the next step) + return ( + tokenAllowances.allowanceFor(tokenAddress) === 0n || + tokenAllowances.allowanceFor(tokenAddress) >= + tokenAmountsToApprove[index + 1].requiredRawAmount + ) + } return requiredRawAmount > 0n && isAllowed }