diff --git a/apps/app/messages/en.json b/apps/app/messages/en.json index 2ecfbada..92e5bdd6 100644 --- a/apps/app/messages/en.json +++ b/apps/app/messages/en.json @@ -156,6 +156,7 @@ "max": "Max", "balance": "Balance:", "enterAnAmount": "Enter an amount", + "approvalButton": "Approve {symbol}", "exactApprovalButton": "Approve exact amount of {symbol}", "exactApprovalTx": "Exact {symbol} Approval", "infiniteApprovalButton": "Approve unlimited amount of {symbol}", diff --git a/shared/react-components/components/Modals/DepositModal/DepositTxButton.tsx b/shared/react-components/components/Modals/DepositModal/DepositTxButton.tsx index 9e90a184..1c3ecfbd 100644 --- a/shared/react-components/components/Modals/DepositModal/DepositTxButton.tsx +++ b/shared/react-components/components/Modals/DepositModal/DepositTxButton.tsx @@ -9,10 +9,10 @@ import { useVaultTokenData } from '@generationsoftware/hyperstructure-react-hooks' import { Intl } from '@shared/types' -import { Button, Spinner } from '@shared/ui' -import { MAX_UINT_256 } from '@shared/utilities' +import { Button } from '@shared/ui' +import { MAX_UINT_256, NETWORK, WRAPPED_NATIVE_ASSETS } from '@shared/utilities' import { useAtomValue } from 'jotai' -import { useEffect } from 'react' +import { ReactNode, useEffect } from 'react' import { Address, parseUnits } from 'viem' import { useAccount, useNetwork } from 'wagmi' import { DepositModalView } from '.' @@ -34,6 +34,7 @@ interface DepositTxButtonProps { intl?: { base?: Intl< | 'enterAnAmount' + | 'approvalButton' | 'exactApprovalButton' | 'exactApprovalTx' | 'infiniteApprovalButton' @@ -173,89 +174,123 @@ export const DepositTxButton = (props: DepositTxButtonProps) => { allowance >= depositAmount && isValidFormTokenAmount + // No deposit amount set if (depositAmount === 0n) { return ( ) - } else if (isDataFetched && allowance < depositAmount) { + } + + const ExactApprovalButton = (props: { children: ReactNode }) => ( + + {props.children} + + ) + + const InfiniteApprovalButton = (props: { children: ReactNode }) => ( + + {props.children} + + ) + + // Needs approval for wrapped native asset + if ( + isDataFetched && + tokenData.address.toLowerCase() === WRAPPED_NATIVE_ASSETS[tokenData.chainId as NETWORK] && + (allowance < depositAmount || allowance > MAX_UINT_256 / 2n) + ) { + return ( + + {intl?.base?.('approvalButton', { symbol: tokenData.symbol }) ?? + `Approve ${tokenData.symbol}`} + + ) + } + + // Needs approval + if (isDataFetched && allowance < depositAmount) { return (
- - {intl?.base?.('exactApprovalButton', { symbol: tokenData?.symbol ?? '?' }) ?? - `Approve exact amount of ${tokenData?.symbol ?? }`} - - - - {intl?.base?.('infiniteApprovalButton', { symbol: tokenData?.symbol ?? '?' }) ?? - `Approve unlimited amount of ${tokenData?.symbol ?? }`} - - + + {intl?.base?.('exactApprovalButton', { symbol: tokenData.symbol }) ?? + `Approve exact amount of ${tokenData.symbol}`} + + + + {intl?.base?.('infiniteApprovalButton', { symbol: tokenData.symbol }) ?? + `Approve unlimited amount of ${tokenData.symbol}`} + +
) - } else if (isDataFetched && modalView === 'main') { + } + + // Prompt to review deposit + if (isDataFetched && modalView === 'main') { return ( ) - } else { - return ( - - {intl?.base?.('confirmDeposit') ?? 'Confirm Deposit'} - - ) } + + // Deposit button + return ( + + {intl?.base?.('confirmDeposit') ?? 'Confirm Deposit'} + + ) } diff --git a/shared/react-components/components/Modals/DepositModal/DepositWithPermitTxButton.tsx b/shared/react-components/components/Modals/DepositModal/DepositWithPermitTxButton.tsx index d39f7647..099f809c 100644 --- a/shared/react-components/components/Modals/DepositModal/DepositWithPermitTxButton.tsx +++ b/shared/react-components/components/Modals/DepositModal/DepositWithPermitTxButton.tsx @@ -206,19 +206,26 @@ export const DepositWithPermitTxButton = (props: DepositWithPermitTxButtonProps) const depositEnabled = isDataFetched && userBalance.amount >= depositAmount && isValidFormTokenAmount + // No deposit amount set if (depositAmount === 0n) { return ( ) - } else if (isDataFetched && modalView === 'main') { + } + + // Prompt to review deposit + if (isDataFetched && modalView === 'main') { return ( ) - } else if (isDataFetched && allowance >= depositAmount) { + } + + // Deposit button + if (isDataFetched && allowance >= depositAmount) { return ( ) - } else { - return ( - - {intl?.base?.('confirmDeposit') ?? 'Confirm Deposit'} - - ) } + + // Sign + deposit with permit button + return ( + + {intl?.base?.('confirmDeposit') ?? 'Confirm Deposit'} + + ) } diff --git a/shared/react-components/components/Modals/DepositModal/index.tsx b/shared/react-components/components/Modals/DepositModal/index.tsx index e24557d7..284be6ba 100644 --- a/shared/react-components/components/Modals/DepositModal/index.tsx +++ b/shared/react-components/components/Modals/DepositModal/index.tsx @@ -43,6 +43,7 @@ export interface DepositModalProps { | 'max' | 'balance' | 'enterAnAmount' + | 'approvalButton' | 'exactApprovalButton' | 'exactApprovalTx' | 'infiniteApprovalButton' diff --git a/shared/utilities/constants.ts b/shared/utilities/constants.ts index fdf3f135..503ab15a 100644 --- a/shared/utilities/constants.ts +++ b/shared/utilities/constants.ts @@ -203,6 +203,30 @@ export const STABLECOINS: Record = { [NETWORK['arbitrum-goerli']]: {} } +/** + * Wrapped native asset addresses (example: WETH, WMATIC, etc.) + * + * NOTE: All addresses are lowercase + */ +export const WRAPPED_NATIVE_ASSETS: Record = { + [NETWORK.mainnet]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + [NETWORK.goerli]: null, + [NETWORK.sepolia]: null, + [NETWORK.bsc]: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c', + [NETWORK['bsc-testnet']]: null, + [NETWORK.xdai]: null, + [NETWORK.polygon]: '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270', + [NETWORK.mumbai]: null, + [NETWORK.optimism]: '0x4200000000000000000000000000000000000006', + [NETWORK['optimism-goerli']]: null, + [NETWORK.avalanche]: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', + [NETWORK.fuji]: null, + [NETWORK.celo]: null, + [NETWORK['celo-testnet']]: null, + [NETWORK.arbitrum]: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + [NETWORK['arbitrum-goerli']]: null +} + /** * RNG auction addresses */