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
*/