From de1d5784045ecd503ada0710ae56bb7d400e3413 Mon Sep 17 00:00:00 2001 From: Bartek Date: Mon, 10 Mar 2025 17:56:18 +0100 Subject: [PATCH 1/5] fix usdc orbit withdrawal --- .../src/hooks/useBalanceOnSourceChain.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/arb-token-bridge-ui/src/hooks/useBalanceOnSourceChain.ts b/packages/arb-token-bridge-ui/src/hooks/useBalanceOnSourceChain.ts index 6c9b135c3e..fb2403bd73 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useBalanceOnSourceChain.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useBalanceOnSourceChain.ts @@ -10,6 +10,7 @@ import { isTokenArbitrumOneNativeUSDC, isTokenArbitrumSepoliaNativeUSDC } from '../util/TokenUtils' +import { isNetwork } from '../util/networks' /** * Balance of the child chain's native currency or ERC20 token @@ -20,6 +21,9 @@ export function useBalanceOnSourceChain( const { address: walletAddress } = useAccount() const [networks] = useNetworks() const { isDepositMode } = useNetworksRelationship(networks) + const { isOrbitChain: isSourceOrbitChain } = isNetwork( + networks.sourceChain.id + ) const { erc20: [erc20SourceChainBalances] @@ -47,7 +51,10 @@ export function useBalanceOnSourceChain( isTokenArbitrumOneNativeUSDC(tokenAddressLowercased) || isTokenArbitrumSepoliaNativeUSDC(tokenAddressLowercased) ) { - return erc20SourceChainBalances[tokenAddressLowercased] ?? constants.Zero + // because we read parent chain address, make sure we don't read Orbit chain's address if it's the source chain + if (!isSourceOrbitChain) { + return erc20SourceChainBalances[tokenAddressLowercased] ?? constants.Zero + } } const tokenChildChainAddress = token.l2Address?.toLowerCase() From 7f06e2aef41eb626d08f60926df0b763e729d425 Mon Sep 17 00:00:00 2001 From: Bartek Date: Tue, 11 Mar 2025 11:01:29 +0100 Subject: [PATCH 2/5] fix usdc token row --- .../components/TransferPanel/TokenSearch.tsx | 81 ++++++++++++++++--- .../src/hooks/useSelectedToken.ts | 2 +- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx index 0be3350d7c..73b3ab5eb0 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx @@ -1,4 +1,10 @@ -import React, { FormEventHandler, useMemo, useState, useCallback } from 'react' +import React, { + FormEventHandler, + useMemo, + useState, + useCallback, + useEffect +} from 'react' import { isAddress } from 'ethers/lib/utils' import Image from 'next/image' import { useAccount } from 'wagmi' @@ -34,7 +40,7 @@ import { TokenRow } from './TokenRow' import { useNetworks } from '../../hooks/useNetworks' import { useNetworksRelationship } from '../../hooks/useNetworksRelationship' import { Switch } from '../common/atoms/Switch' -import { useSelectedToken } from '../../hooks/useSelectedToken' +import { getUsdcToken, useSelectedToken } from '../../hooks/useSelectedToken' import { useBalances } from '../../hooks/useBalances' import { useSetInputAmount } from '../../hooks/TransferPanel/useSetInputAmount' import { addressesEqual } from '../../util/AddressUtils' @@ -172,8 +178,13 @@ function TokensPanel({ } } = useAppState() const [networks] = useNetworks() - const { childChain, childChainProvider, parentChain, isDepositMode } = - useNetworksRelationship(networks) + const { + childChain, + childChainProvider, + parentChain, + parentChainProvider, + isDepositMode + } = useNetworksRelationship(networks) const { ethParentBalance, erc20ParentBalances, @@ -187,6 +198,8 @@ function TokensPanel({ const nativeCurrency = useNativeCurrency({ provider: childChainProvider }) const { + isEthereumMainnet: isParentChainEthereumMainnet, + isSepolia: isParentChainSepolia, isArbitrumOne: isParentChainArbitrumOne, isArbitrumSepolia: isParentChainArbitrumSepolia } = isNetwork(parentChain.id) @@ -199,6 +212,7 @@ function TokensPanel({ const [newToken, setNewToken] = useState('') const [errorMessage, setErrorMessage] = useState('') const [isAddingToken, setIsAddingToken] = useState(false) + const [usdcToken, setUsdcToken] = useState(null) const getBalance = useCallback( (address: string) => { @@ -241,6 +255,53 @@ function TokensPanel({ ] ) + const usdcParentAddress = useMemo(() => { + if (isParentChainEthereumMainnet) { + return CommonAddress.Ethereum.USDC + } + if (isParentChainSepolia) { + return CommonAddress.Sepolia.USDC + } + if (isParentChainArbitrumOne) { + return CommonAddress.ArbitrumOne.USDC + } + if (isParentChainArbitrumSepolia) { + return CommonAddress.ArbitrumSepolia.USDC + } + }, [ + isParentChainEthereumMainnet, + isParentChainSepolia, + isParentChainArbitrumOne, + isParentChainArbitrumSepolia + ]) + + useEffect(() => { + async function _getUsdcToken() { + console.log({ usdcParentAddress }) + if (!usdcParentAddress) { + return + } + + const token = await getUsdcToken({ + tokenAddress: usdcParentAddress, + parentProvider: parentChainProvider, + childProvider: childChainProvider + }) + + console.log('fetched token: ', token) + + setUsdcToken(token) + } + + _getUsdcToken() + }, [ + usdcParentAddress, + getUsdcToken, + setUsdcToken, + parentChainProvider, + childChainProvider + ]) + const tokensToShow = useMemo(() => { const tokenSearch = newToken.trim().toLowerCase() const tokenAddresses = [ @@ -430,10 +491,12 @@ function TokensPanel({ const address = tokensToShow[virtualizedProps.index] let token: ERC20BridgeToken | null = null - if (isTokenArbitrumOneNativeUSDC(address)) { - token = ARB_ONE_NATIVE_USDC_TOKEN - } else if (isTokenArbitrumSepoliaNativeUSDC(address)) { - token = ARB_SEPOLIA_NATIVE_USDC_TOKEN + if ( + isTokenArbitrumOneNativeUSDC(address) || + isTokenArbitrumSepoliaNativeUSDC(address) + ) { + console.log({ usdcToken }) + token = usdcToken } else if (address) { token = tokensFromLists[address] || tokensFromUser[address] || null } @@ -457,7 +520,7 @@ function TokensPanel({ /> ) }, - [tokensToShow, tokensFromLists, tokensFromUser, onTokenSelected] + [tokensToShow, tokensFromLists, tokensFromUser, onTokenSelected, usdcToken] ) const AddButton = useMemo( diff --git a/packages/arb-token-bridge-ui/src/hooks/useSelectedToken.ts b/packages/arb-token-bridge-ui/src/hooks/useSelectedToken.ts index 503855e1d4..acc1e0622b 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useSelectedToken.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useSelectedToken.ts @@ -97,7 +97,7 @@ function sanitizeTokenAddress(tokenAddress: string | null): string | undefined { return undefined } -async function getUsdcToken({ +export async function getUsdcToken({ tokenAddress, parentProvider, childProvider From 211d032e7771f8f47af5d328eb00aab3485b27df Mon Sep 17 00:00:00 2001 From: Bartek Date: Tue, 11 Mar 2025 12:53:58 +0100 Subject: [PATCH 3/5] remove logs --- .../src/components/TransferPanel/TokenSearch.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx index 73b3ab5eb0..ed5d969b29 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx @@ -277,7 +277,6 @@ function TokensPanel({ useEffect(() => { async function _getUsdcToken() { - console.log({ usdcParentAddress }) if (!usdcParentAddress) { return } @@ -288,8 +287,6 @@ function TokensPanel({ childProvider: childChainProvider }) - console.log('fetched token: ', token) - setUsdcToken(token) } @@ -495,7 +492,6 @@ function TokensPanel({ isTokenArbitrumOneNativeUSDC(address) || isTokenArbitrumSepoliaNativeUSDC(address) ) { - console.log({ usdcToken }) token = usdcToken } else if (address) { token = tokensFromLists[address] || tokensFromUser[address] || null From 71fd02490daed26b06fb79c8b0e994f0af5b9da8 Mon Sep 17 00:00:00 2001 From: Bartek Date: Tue, 11 Mar 2025 15:27:50 +0100 Subject: [PATCH 4/5] use swr --- .../components/TransferPanel/TokenSearch.tsx | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx index ed5d969b29..68d02f2c84 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx @@ -1,15 +1,10 @@ -import React, { - FormEventHandler, - useMemo, - useState, - useCallback, - useEffect -} from 'react' +import React, { FormEventHandler, useMemo, useState, useCallback } from 'react' import { isAddress } from 'ethers/lib/utils' import Image from 'next/image' import { useAccount } from 'wagmi' import { AutoSizer, List, ListRowProps } from 'react-virtualized' import { twMerge } from 'tailwind-merge' +import useSWRImmutable from 'swr/immutable' import { useAppState } from '../../state' import { @@ -44,6 +39,7 @@ import { getUsdcToken, useSelectedToken } from '../../hooks/useSelectedToken' import { useBalances } from '../../hooks/useBalances' import { useSetInputAmount } from '../../hooks/TransferPanel/useSetInputAmount' import { addressesEqual } from '../../util/AddressUtils' +import { getProviderForChainId } from '@/token-bridge-sdk/utils' export const ARB_ONE_NATIVE_USDC_TOKEN = { ...ArbOneNativeUSDC, @@ -212,7 +208,6 @@ function TokensPanel({ const [newToken, setNewToken] = useState('') const [errorMessage, setErrorMessage] = useState('') const [isAddingToken, setIsAddingToken] = useState(false) - const [usdcToken, setUsdcToken] = useState(null) const getBalance = useCallback( (address: string) => { @@ -275,29 +270,22 @@ function TokensPanel({ isParentChainArbitrumSepolia ]) - useEffect(() => { - async function _getUsdcToken() { - if (!usdcParentAddress) { - return - } - - const token = await getUsdcToken({ - tokenAddress: usdcParentAddress, - parentProvider: parentChainProvider, - childProvider: childChainProvider + const { data: usdcToken = null } = useSWRImmutable( + usdcParentAddress + ? ([ + usdcParentAddress, + parentChain.id, + childChain.id, + 'token_search_usdc_token' + ] as const) + : null, + ([_usdcParentAddress, _parentChainId, _childChainId]) => + getUsdcToken({ + tokenAddress: _usdcParentAddress, + parentProvider: getProviderForChainId(_parentChainId), + childProvider: getProviderForChainId(_childChainId) }) - - setUsdcToken(token) - } - - _getUsdcToken() - }, [ - usdcParentAddress, - getUsdcToken, - setUsdcToken, - parentChainProvider, - childChainProvider - ]) + ) const tokensToShow = useMemo(() => { const tokenSearch = newToken.trim().toLowerCase() From d2b4329b68484f6dca8d1e37c45640af1fc6cba9 Mon Sep 17 00:00:00 2001 From: Bartek Date: Tue, 11 Mar 2025 15:29:33 +0100 Subject: [PATCH 5/5] clean up --- .../src/components/TransferPanel/TokenSearch.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx index 68d02f2c84..2fb588a1af 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx @@ -174,13 +174,8 @@ function TokensPanel({ } } = useAppState() const [networks] = useNetworks() - const { - childChain, - childChainProvider, - parentChain, - parentChainProvider, - isDepositMode - } = useNetworksRelationship(networks) + const { childChain, childChainProvider, parentChain, isDepositMode } = + useNetworksRelationship(networks) const { ethParentBalance, erc20ParentBalances,