@@ -9,7 +9,7 @@ import React, { useEffect, useMemo, useState } from 'react';
99import { Link } from 'src/components/primitives/Link' ;
1010import { Warning } from 'src/components/primitives/Warning' ;
1111import { ConnectWalletButton } from 'src/components/WalletConnection/ConnectWalletButton' ;
12- import { isSmartContractWallet } from 'src/helpers/provider' ;
12+ import { isSafeWallet , isSmartContractWallet } from 'src/helpers/provider' ;
1313import { TokenInfoWithBalance , useTokensBalance } from 'src/hooks/generic/useTokensBalance' ;
1414import { useMultiProviderSwitchRates } from 'src/hooks/switch/useMultiProviderSwitchRates' ;
1515import { useSwitchProvider } from 'src/hooks/switch/useSwitchProvider' ;
@@ -55,6 +55,9 @@ export type SwitchDetailsParams = Parameters<
5555> [ 0 ] ;
5656
5757const valueLostPercentage = ( destValueInUsd : number , srcValueInUsd : number ) => {
58+ if ( destValueInUsd === 0 ) return 1 ;
59+ if ( srcValueInUsd === 0 ) return 0 ;
60+
5861 const receivingPercentage = destValueInUsd / srcValueInUsd ;
5962 const valueLostPercentage = receivingPercentage ? 1 - receivingPercentage : 0 ;
6063 return valueLostPercentage ;
@@ -158,8 +161,10 @@ export const BaseSwitchModalContent = ({
158161 return forcedChainId ;
159162 return defaultNetwork . chainId ;
160163 } ) ;
164+ const trackEvent = useRootStore ( ( store ) => store . trackEvent ) ;
165+ const [ showUSDTResetWarning , setShowUSDTResetWarning ] = useState ( false ) ;
161166 const switchProvider = useSwitchProvider ( { chainId : selectedChainId } ) ;
162- const [ slippage , setSlippage ] = useState ( switchProvider == 'cowprotocol' ? '2 ' : '0.10' ) ;
167+ const [ slippage , setSlippage ] = useState ( switchProvider == 'cowprotocol' ? '0.5 ' : '0.10' ) ;
163168 const [ showGasStation , setShowGasStation ] = useState ( switchProvider == 'paraswap' ) ;
164169 const [ highPriceImpactConfirmed , setHighPriceImpactConfirmed ] = useState ( false ) ;
165170 const selectedNetworkConfig = getNetworkConfig ( selectedChainId ) ;
@@ -173,13 +178,17 @@ export const BaseSwitchModalContent = ({
173178 ) ;
174179
175180 const [ userIsSmartContractWallet , setUserIsSmartContractWallet ] = useState ( false ) ;
181+ const [ userIsSafeWallet , setUserIsSafeWallet ] = useState ( false ) ;
176182 useEffect ( ( ) => {
177183 try {
178184 if ( user && connectedChainId ) {
179185 getEthersProvider ( wagmiConfig , { chainId : connectedChainId } ) . then ( ( provider ) => {
180- isSmartContractWallet ( user , provider ) . then ( ( isSmartContractWallet ) => {
181- setUserIsSmartContractWallet ( isSmartContractWallet ) ;
182- } ) ;
186+ Promise . all ( [ isSmartContractWallet ( user , provider ) , isSafeWallet ( user , provider ) ] ) . then (
187+ ( [ isSmartContract , isSafe ] ) => {
188+ setUserIsSmartContractWallet ( isSmartContract ) ;
189+ setUserIsSafeWallet ( isSafe ) ;
190+ }
191+ ) ;
183192 } ) ;
184193 }
185194 } catch ( error ) {
@@ -326,6 +335,7 @@ export const BaseSwitchModalContent = ({
326335 isNativeToken ( selectedInputToken ?. address ) ,
327336 switchProvider
328337 ) ;
338+
329339 const safeSlippage =
330340 slippageValidation && slippageValidation . severity === ValidationSeverity . ERROR
331341 ? 0
@@ -357,6 +367,52 @@ export const BaseSwitchModalContent = ({
357367 isTxSuccess : switchTxState . success ,
358368 } ) ;
359369
370+ useEffect ( ( ) => {
371+ if ( ratesError ) {
372+ console . error ( 'tracking error' , ratesError ) ;
373+ trackEvent ( 'Swap Error' , {
374+ 'Error Message' : ratesError . message ,
375+ 'Error Name' : ratesError . name ,
376+ 'Error Stack' : ratesError . stack ,
377+ 'Input Token' : selectedInputToken . symbol ,
378+ 'Output Token' : selectedOutputToken . symbol ,
379+ 'Input Amount' : debounceInputAmount ,
380+ 'Output Amount' : normalizeBN (
381+ switchRates ?. provider === 'cowprotocol'
382+ ? switchRates ?. destSpot
383+ : switchRates ?. destAmount || 0 ,
384+ switchRates ?. destDecimals || 18
385+ ) . toString ( ) ,
386+ 'Input Amount USD' : switchRates ?. srcUSD ,
387+ 'Output Amount USD' : switchRates ?. destUSD ,
388+ Slippage : safeSlippage ,
389+ } ) ;
390+ }
391+ } , [ ratesError ] ) ;
392+
393+ useEffect ( ( ) => {
394+ if ( txError && txError . actionBlocked ) {
395+ console . error ( 'tracking error' , txError ) ;
396+ trackEvent ( 'Swap Tx Error' , {
397+ 'Error Message' : txError . error ?. toString ( ) ,
398+ 'Error Raw' : txError . rawError ?. toString ( ) ,
399+ 'Error Action' : txError . txAction ,
400+ 'Input Token' : selectedInputToken . symbol ,
401+ 'Output Token' : selectedOutputToken . symbol ,
402+ 'Input Amount' : debounceInputAmount ,
403+ 'Output Amount' : normalizeBN (
404+ switchRates ?. provider === 'cowprotocol'
405+ ? switchRates ?. destSpot
406+ : switchRates ?. destAmount || 0 ,
407+ switchRates ?. destDecimals || 18
408+ ) . toString ( ) ,
409+ 'Input Amount USD' : switchRates ?. srcUSD ,
410+ 'Output Amount USD' : switchRates ?. destUSD ,
411+ Slippage : safeSlippage ,
412+ } ) ;
413+ }
414+ } , [ txError ] ) ;
415+
360416 // Define default slippage for CoW
361417 useEffect ( ( ) => {
362418 if ( switchProvider == 'cowprotocol' && isCowProtocolRates ( switchRates ) ) {
@@ -445,13 +501,19 @@ export const BaseSwitchModalContent = ({
445501
446502 // Eth-Flow requires to leave some assets for gas
447503 const nativeDecimals = 18 ;
448- const gasRequiredForEthFlow = parseUnits ( '0.01' , nativeDecimals ) ; // TODO: Ask for better value coming from the SDK
449- const requiredAssetsLeftForGas = isNativeToken ( selectedInputToken . address )
450- ? gasRequiredForEthFlow
451- : undefined ;
452- const maxAmount = requiredAssetsLeftForGas
453- ? parseUnits ( selectedInputToken . balance , nativeDecimals ) - requiredAssetsLeftForGas
454- : undefined ;
504+ const gasRequiredForEthFlow =
505+ selectedChainId === 1
506+ ? parseUnits ( '0.01' , nativeDecimals )
507+ : parseUnits ( '0.0001' , nativeDecimals ) ; // TODO: Ask for better value coming from the SDK
508+ const requiredAssetsLeftForGas =
509+ isNativeToken ( selectedInputToken . address ) && ! userIsSmartContractWallet
510+ ? gasRequiredForEthFlow
511+ : undefined ;
512+ const maxAmount = ( ( ) => {
513+ const balance = parseUnits ( selectedInputToken . balance , nativeDecimals ) ;
514+ if ( ! requiredAssetsLeftForGas ) return balance ;
515+ return balance > requiredAssetsLeftForGas ? balance - requiredAssetsLeftForGas : balance ;
516+ } ) ( ) ;
455517 const maxAmountFormatted = maxAmount
456518 ? normalize ( maxAmount . toString ( ) , nativeDecimals ) . toString ( )
457519 : undefined ;
@@ -494,11 +556,7 @@ export const BaseSwitchModalContent = ({
494556 return (
495557 < >
496558 { showTitle && (
497- < TxModalTitle
498- title = { `Swap ${
499- debounceInputAmount . length && selectedInputToken ? selectedInputToken . symbol : 'Assets'
500- } `}
501- />
559+ < TxModalTitle title = { `Swap ${ selectedInputToken ? selectedInputToken . symbol : 'Assets' } ` } />
502560 ) }
503561 { showChangeNetworkWarning && isWrongNetwork . isWrongNetwork && ! readOnlyModeAddress && (
504562 < ChangeNetworkWarning
@@ -536,6 +594,11 @@ export const BaseSwitchModalContent = ({
536594 slippageValidation = { slippageValidation }
537595 slippage = { slippage }
538596 setSlippage = { setSlippage }
597+ suggestedSlippage = {
598+ switchRates ?. provider === 'cowprotocol'
599+ ? switchRates ?. suggestedSlippage . toString ( )
600+ : undefined
601+ }
539602 />
540603 </ Box >
541604 { ! selectedInputToken || ! selectedOutputToken ? (
@@ -559,16 +622,21 @@ export const BaseSwitchModalContent = ({
559622 ( token ) =>
560623 token . address !== selectedOutputToken . address &&
561624 Number ( token . balance ) !== 0 &&
625+ // Remove native tokens for non-Safe smart contract wallets
626+ ! ( userIsSmartContractWallet && ! userIsSafeWallet && token . extensions ?. isNative ) &&
562627 // Avoid wrapping
563628 ! (
564629 isNativeToken ( selectedOutputToken . address ) &&
565- token . address ===
566- WRAPPED_NATIVE_CURRENCIES [ selectedChainId as SupportedChainId ] ?. address
630+ token . address . toLowerCase ( ) ===
631+ WRAPPED_NATIVE_CURRENCIES [
632+ selectedChainId as SupportedChainId
633+ ] ?. address . toLowerCase ( )
567634 ) &&
568635 ! (
569- selectedOutputToken . address ===
570- WRAPPED_NATIVE_CURRENCIES [ selectedChainId as SupportedChainId ] ?. address &&
571- isNativeToken ( token . address )
636+ selectedOutputToken . address . toLowerCase ( ) ===
637+ WRAPPED_NATIVE_CURRENCIES [
638+ selectedChainId as SupportedChainId
639+ ] ?. address . toLowerCase ( ) && isNativeToken ( token . address )
572640 )
573641 ) }
574642 value = { inputAmount }
@@ -608,21 +676,29 @@ export const BaseSwitchModalContent = ({
608676 // Avoid wrapping
609677 ! (
610678 isNativeToken ( selectedInputToken . address ) &&
611- token . address ===
612- WRAPPED_NATIVE_CURRENCIES [ selectedChainId as SupportedChainId ] ?. address
679+ token . address . toLowerCase ( ) ===
680+ WRAPPED_NATIVE_CURRENCIES [
681+ selectedChainId as SupportedChainId
682+ ] ?. address . toLowerCase ( )
613683 ) &&
614684 ! (
615- selectedInputToken . address ===
616- WRAPPED_NATIVE_CURRENCIES [ selectedChainId as SupportedChainId ] ?. address &&
617- isNativeToken ( token . address )
685+ selectedInputToken . address . toLowerCase ( ) ===
686+ WRAPPED_NATIVE_CURRENCIES [
687+ selectedChainId as SupportedChainId
688+ ] ?. address . toLowerCase ( ) && isNativeToken ( token . address )
618689 )
619690 ) }
620- value = {
621- switchRates
622- ? normalizeBN ( switchRates . destAmount , switchRates . destDecimals ) . toString ( )
623- : '0'
691+ value = { normalizeBN (
692+ switchRates ?. provider === 'cowprotocol'
693+ ? switchRates ?. destSpot
694+ : switchRates ?. destAmount || 0 ,
695+ switchRates ?. destDecimals || 18
696+ ) . toString ( ) }
697+ usdValue = {
698+ switchRates ?. provider === 'cowprotocol'
699+ ? switchRates ?. destSpotInUsd
700+ : switchRates ?. destUSD || '0'
624701 }
625- usdValue = { switchRates ?. destUSD || '0' }
626702 loading = {
627703 debounceInputAmount !== '0' &&
628704 debounceInputAmount !== '' &&
@@ -667,6 +743,17 @@ export const BaseSwitchModalContent = ({
667743 </ Warning >
668744 ) }
669745
746+ { showUSDTResetWarning && (
747+ < Warning severity = "info" sx = { { mt : 5 } } >
748+ < Typography variant = "caption" >
749+ < Trans >
750+ USDT on Ethereum requires approval reset before a new approval. This will
751+ require an additional transaction.
752+ </ Trans >
753+ </ Typography >
754+ </ Warning >
755+ ) }
756+
670757 < SwitchErrors
671758 ratesError = { ratesError }
672759 balance = { selectedInputToken . balance }
@@ -733,8 +820,7 @@ export const BaseSwitchModalContent = ({
733820 inputAmount = { debounceInputAmount }
734821 inputToken = { selectedInputToken . address }
735822 outputToken = { selectedOutputToken . address }
736- inputName = { selectedInputToken . name }
737- outputName = { selectedOutputToken . name }
823+ setShowUSDTResetWarning = { setShowUSDTResetWarning }
738824 inputSymbol = { selectedInputToken . symbol }
739825 outputSymbol = { selectedOutputToken . symbol }
740826 slippage = { safeSlippage . toString ( ) }
0 commit comments