From 05b39e2c080b1ca7e148e7d8cf3801297c758ee4 Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Thu, 7 Mar 2024 14:21:31 +0000 Subject: [PATCH] fix(trading): usdt approvals (#5939) --- libs/assets/src/lib/constants.ts | 7 +++ .../deposits/src/lib/approve-notification.tsx | 52 +++++++++++++------ libs/deposits/src/lib/deposit-form.tsx | 6 +-- libs/deposits/src/lib/use-submit-approval.ts | 4 +- libs/i18n/src/locales/en/deposits.json | 2 + .../lib/use-ethereum-transaction-manager.tsx | 2 + 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/libs/assets/src/lib/constants.ts b/libs/assets/src/lib/constants.ts index 503e4e460..825df45e1 100644 --- a/libs/assets/src/lib/constants.ts +++ b/libs/assets/src/lib/constants.ts @@ -62,3 +62,10 @@ export const DENY_LIST: Record = { 'fdf0ec118d98393a7702cf72e46fc87ad680b152f64b2aac59e093ac2d688fbb', ], }; + +// We need a record of USDT on mainnet as it needs special handling for +// deposits and approvals due to the contract not conforming exactly +// to ERC20 +export const USDT_ID = { + MAINNET: 'bf1e88d19db4b3ca0d1d5bdb73718a01686b18cf731ca26adedf3c8b83802bba', +} as const; diff --git a/libs/deposits/src/lib/approve-notification.tsx b/libs/deposits/src/lib/approve-notification.tsx index 9f03c3812..8d4a9499b 100644 --- a/libs/deposits/src/lib/approve-notification.tsx +++ b/libs/deposits/src/lib/approve-notification.tsx @@ -1,5 +1,9 @@ -import type { Asset } from '@vegaprotocol/assets'; -import { EtherscanLink } from '@vegaprotocol/environment'; +import { USDT_ID, type Asset } from '@vegaprotocol/assets'; +import { + EtherscanLink, + Networks, + useEnvironment, +} from '@vegaprotocol/environment'; import { Intent, Notification } from '@vegaprotocol/ui-toolkit'; import { formatNumber, @@ -15,7 +19,7 @@ import { useT } from './use-t'; interface ApproveNotificationProps { isActive: boolean; selectedAsset?: Asset; - onApprove: () => void; + onApprove: (amount?: string) => void; approved: boolean; balances: DepositBalances | null; amount: string; @@ -33,6 +37,7 @@ export const ApproveNotification = ({ approveTxId, intent = Intent.Warning, }: ApproveNotificationProps) => { + const { VEGA_ENV } = useEnvironment(); const t = useT(); const tx = useEthTransactionStore((state) => { return state.transactions.find((t) => t?.id === approveTxId); @@ -64,28 +69,45 @@ export const ApproveNotification = ({ text: t('Approve {{assetSymbol}}', { assetSymbol: selectedAsset?.symbol, }), - action: onApprove, + action: () => onApprove(), dataTestId: 'approve-submit', }} /> ); + + let message = t('Approve again to deposit more than {{allowance}}', { + allowance: formatNumber(balances.allowance.toString()), + }); + const buttonProps = { + size: 'small' as const, + text: t('Approve {{assetSymbol}}', { + assetSymbol: selectedAsset?.symbol, + }), + action: () => onApprove(), + dataTestId: 'reapprove-submit', + }; + + if (VEGA_ENV === Networks.MAINNET && selectedAsset.id === USDT_ID[VEGA_ENV]) { + message = t( + 'USDT approved amount cannot be changed, only revoked. Revoke and reapprove to deposit more than {{allowance}}.', + { + allowance: formatNumber(balances.allowance.toString()), + } + ); + buttonProps.text = t('Revoke {{assetSymbol}} approval', { + assetSymbol: selectedAsset?.symbol, + }); + buttonProps.action = () => onApprove('0'); + } + const reApprovePrompt = (
); diff --git a/libs/deposits/src/lib/deposit-form.tsx b/libs/deposits/src/lib/deposit-form.tsx index d631e8c4f..16dd48b90 100644 --- a/libs/deposits/src/lib/deposit-form.tsx +++ b/libs/deposits/src/lib/deposit-form.tsx @@ -58,7 +58,7 @@ export interface DepositFormProps { onSelectAsset: (assetId: string) => void; handleAmountChange: (amount: string) => void; onDisconnect: () => void; - submitApprove: () => void; + submitApprove: (amount?: string) => void; approveTxId: number | null; submitFaucet: () => void; faucetTxId: number | null; @@ -423,8 +423,8 @@ export const DepositForm = ({ isActive={isActive} approveTxId={approveTxId} selectedAsset={selectedAsset} - onApprove={() => { - submitApprove(); + onApprove={(amount) => { + submitApprove(amount); setApproveNotificationIntent(Intent.Warning); }} balances={balances} diff --git a/libs/deposits/src/lib/use-submit-approval.ts b/libs/deposits/src/lib/use-submit-approval.ts index 81290155f..e24a76da6 100644 --- a/libs/deposits/src/lib/use-submit-approval.ts +++ b/libs/deposits/src/lib/use-submit-approval.ts @@ -35,11 +35,11 @@ export const useSubmitApproval = ( reset: () => { setId(null); }, - perform: () => { + perform: (amount?: string) => { if (!asset || !config) return; const id = createEthTransaction(contract, 'approve', [ config?.collateral_bridge_contract.address, - MaxUint256.toString(), + amount ? amount : MaxUint256.toString(), ]); setId(id); }, diff --git a/libs/i18n/src/locales/en/deposits.json b/libs/i18n/src/locales/en/deposits.json index c1c5d6dc8..c360e195e 100644 --- a/libs/i18n/src/locales/en/deposits.json +++ b/libs/i18n/src/locales/en/deposits.json @@ -4,6 +4,7 @@ "Approval failed": "Approval failed", "Approve {{assetSymbol}}": "Approve {{assetSymbol}}", "Approve again to deposit more than {{allowance}}": "Approve again to deposit more than {{allowance}}", + "USDT approved amount cannot be changed, only revoked. Revoke and reapprove to deposit more than {{allowance}}.": "USDT approved amount cannot be changed, only revoked. Revoke and reapprove to deposit more than {{allowance}}.", "Asset": "Asset", "Balance available": "Balance available", "Before you can make a deposit of your chosen asset, {{assetSymbol}}, you need to approve its use in your Ethereum wallet": "Before you can make a deposit of your chosen asset, {{assetSymbol}}, you need to approve its use in your Ethereum wallet", @@ -23,6 +24,7 @@ "Please select": "Please select", "Please select an asset": "Please select an asset", "Remaining deposit allowance": "Remaining deposit allowance", + "Revoke {{assetSymbol}} approval": "Revoke {{assetSymbol}} approval", "Select from wallet": "Select from wallet", "The {{symbol}} faucet is not available at this time": "The {{symbol}} faucet is not available at this time", "The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.": "The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.", diff --git a/libs/web3/src/lib/use-ethereum-transaction-manager.tsx b/libs/web3/src/lib/use-ethereum-transaction-manager.tsx index 8bcc136ae..501bc93cc 100644 --- a/libs/web3/src/lib/use-ethereum-transaction-manager.tsx +++ b/libs/web3/src/lib/use-ethereum-transaction-manager.tsx @@ -27,6 +27,7 @@ export const useEthTransactionManager = () => { confirmations: 0, notify: true, }); + const { contract, methodName, @@ -44,6 +45,7 @@ export const useEthTransactionManager = () => { ) { throw new Error('method not found on contract'); } + await contract.contract.callStatic[methodName](...args); } catch (err) { update(transaction.id, {