diff --git a/src/handlers/swap.ts b/src/handlers/swap.ts index d814320dd6a..8dacc675b13 100644 --- a/src/handlers/swap.ts +++ b/src/handlers/swap.ts @@ -1,7 +1,6 @@ import { BigNumberish } from '@ethersproject/bignumber'; import { Block, StaticJsonRpcProvider } from '@ethersproject/providers'; import { - ALLOWS_PERMIT, CrosschainQuote, getQuoteExecutionDetails, getRainbowRouterContractAddress, @@ -86,14 +85,7 @@ const getCrosschainSwapRainbowDefaultGasLimit = (chainId: ChainId) => ethereumUtils.getBasicSwapGasLimit(Number(chainId)) * EXTRA_GAS_PADDING; export const getDefaultGasLimitForTrade = (tradeDetails: Quote, chainId: ChainId): number => { - const allowsPermit = - chainId === ChainId.mainnet && ALLOWS_PERMIT[tradeDetails?.sellTokenAddress?.toLowerCase() as keyof PermitSupportedTokenList]; - - let defaultGasLimit = tradeDetails?.defaultGasLimit; - - if (allowsPermit) { - defaultGasLimit = Math.max(Number(defaultGasLimit), Number(ethUnits.basic_swap_permit) * EXTRA_GAS_PADDING).toString(); - } + const defaultGasLimit = tradeDetails?.defaultGasLimit; return Number(defaultGasLimit || 0) || ethereumUtils.getBasicSwapGasLimit(Number(chainId)) * EXTRA_GAS_PADDING; }; diff --git a/src/raps/actions/swap.ts b/src/raps/actions/swap.ts index a2331a9fcd3..12164beb055 100644 --- a/src/raps/actions/swap.ts +++ b/src/raps/actions/swap.ts @@ -205,9 +205,10 @@ export const executeSwap = async ({ wallet: Signer; permit: boolean; }): Promise => { - if (!wallet || !quote) return null; + if (!wallet || !quote) { + return null; + } - const { sellTokenAddress, buyTokenAddress } = quote; const transactionParams = { gasLimit: toHex(gasLimit) || undefined, nonce: nonce ? toHex(`${nonce}`) : undefined, @@ -236,9 +237,8 @@ export const swap = async ({ gasFeeParamsBySpeed, }: ActionProps<'swap'>): Promise => { let gasParamsToUse = gasParams; - // let gasParams = parseGasParamAmounts(selectedGasFee); - const { quote, permit, chainId, requiresApprove } = parameters; + const { quote, chainId, requiresApprove } = parameters; // if swap isn't the last action, use fast gas or custom (whatever is faster) if (currentRap.actions.length - 1 > index) { @@ -272,7 +272,7 @@ export const swap = async ({ chainId, gasLimit, nonce, - permit: !!permit, + permit: false, quote, wallet, }; diff --git a/src/raps/execute.ts b/src/raps/execute.ts index 3ee2c9ec9b4..ba9b4ab9a07 100644 --- a/src/raps/execute.ts +++ b/src/raps/execute.ts @@ -2,7 +2,7 @@ /* eslint-disable no-async-promise-executor */ /* eslint-disable no-promise-executor-return */ import { Signer } from '@ethersproject/abstract-signer'; - +import { ChainId } from '@/chains/types'; import { RainbowError, logger } from '@/logger'; import { claim, swap, unlock } from './actions'; @@ -111,18 +111,29 @@ function getRapFullName(actions: RapAction[]) { const delay = (ms: number) => new Promise(res => setTimeout(res, ms)); -const waitForNodeAck = async (hash: string, provider: Signer['provider']): Promise => { - return new Promise(async resolve => { +const NODE_ACK_MAX_TRIES = 10; + +const waitForNodeAck = async (hash: string, provider: Signer['provider'], tries = 0): Promise => { + try { const tx = await provider?.getTransaction(hash); + // This means the node is aware of the tx, we're good to go if ((tx && tx.blockNumber === null) || (tx && tx?.blockNumber && tx?.blockNumber > 0)) { - resolve(); - } else { - // Wait for 1 second and try again + return; + } + + // Wait for 1 second and try again + if (tries < NODE_ACK_MAX_TRIES) { await delay(1000); - return waitForNodeAck(hash, provider); + return waitForNodeAck(hash, provider, tries + 1); } - }); + } catch (e) { + // Wait for 1 second and try again + if (tries < NODE_ACK_MAX_TRIES) { + await delay(1000); + return waitForNodeAck(hash, provider, tries + 1); + } + } }; export const walletExecuteRap = async ( @@ -161,11 +172,13 @@ export const walletExecuteRap = async ( gasFeeParamsBySpeed: parameters?.gasFeeParamsBySpeed, }; - const { baseNonce, errorMessage: error, hash } = await executeAction(actionParams); + const { baseNonce, errorMessage: error, hash: firstHash } = await executeAction(actionParams); + const shouldWaitForNodeAck = parameters.chainId !== ChainId.mainnet; if (typeof baseNonce === 'number') { - actions.length > 1 && hash && (await waitForNodeAck(hash, wallet.provider)); + let latestHash = firstHash; for (let index = 1; index < actions.length; index++) { + latestHash && shouldWaitForNodeAck && (await waitForNodeAck(latestHash, wallet.provider)); const action = actions[index]; const actionParams = { action, @@ -178,8 +191,8 @@ export const walletExecuteRap = async ( gasParams: parameters?.gasParams, gasFeeParamsBySpeed: parameters?.gasFeeParamsBySpeed, }; - const { hash } = await executeAction(actionParams); - hash && (await waitForNodeAck(hash, wallet.provider)); + const { hash: nextHash } = await executeAction(actionParams); + latestHash = nextHash; } nonce = baseNonce + actions.length - 1; } else { diff --git a/src/raps/unlockAndSwap.ts b/src/raps/unlockAndSwap.ts index 01d226f2703..bdf1f9fb9f6 100644 --- a/src/raps/unlockAndSwap.ts +++ b/src/raps/unlockAndSwap.ts @@ -1,15 +1,7 @@ -import { - ALLOWS_PERMIT, - ETH_ADDRESS as ETH_ADDRESS_AGGREGATOR, - getRainbowRouterContractAddress, - PermitSupportedTokenList, -} from '@rainbow-me/swaps'; +import { getRainbowRouterContractAddress } from '@rainbow-me/swaps'; import { Address } from 'viem'; -import { ChainId } from '@/chains/types'; -import { isNativeAsset } from '@/handlers/assets'; import { add } from '@/helpers/utilities'; -import { isLowerCaseMatch } from '@/utils'; import { assetNeedsUnlocking, estimateApprove, estimateSwapGasLimit } from './actions'; import { estimateUnlockAndSwapFromMetadata } from './actions/swap'; @@ -56,7 +48,6 @@ export const estimateUnlockAndSwap = async ({ if (gasLimitFromMetadata) { return gasLimitFromMetadata; } - const unlockGasLimit = await estimateApprove({ owner: accountAddress, tokenAddress: sellTokenAddress, @@ -89,19 +80,12 @@ export const createUnlockAndSwapRap = async (swapParameters: RapSwapActionParame const { sellAmount, quote, chainId, assetToSell, assetToBuy } = swapParameters; - const { - from: accountAddress, - sellTokenAddress, - allowanceNeeded, - } = quote as { + const { from: accountAddress, allowanceNeeded } = quote as { from: Address; sellTokenAddress: Address; allowanceNeeded: boolean; }; - // Aggregators represent native asset as 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE - const nativeAsset = isLowerCaseMatch(ETH_ADDRESS_AGGREGATOR, sellTokenAddress) || isNativeAsset(sellTokenAddress, chainId); - let swapAssetNeedsUnlocking = false; if (allowanceNeeded) { @@ -114,10 +98,7 @@ export const createUnlockAndSwapRap = async (swapParameters: RapSwapActionParame }); } - const allowsPermit = - !nativeAsset && chainId === ChainId.mainnet && ALLOWS_PERMIT[assetToSell.address?.toLowerCase() as keyof PermitSupportedTokenList]; - - if (swapAssetNeedsUnlocking && !allowsPermit) { + if (swapAssetNeedsUnlocking) { const unlock = createNewAction('unlock', { fromAddress: accountAddress, amount: sellAmount, @@ -132,8 +113,8 @@ export const createUnlockAndSwapRap = async (swapParameters: RapSwapActionParame const swap = createNewAction('swap', { chainId, sellAmount, - permit: swapAssetNeedsUnlocking && allowsPermit, - requiresApprove: swapAssetNeedsUnlocking && !allowsPermit, + permit: false, + requiresApprove: swapAssetNeedsUnlocking, quote, meta: swapParameters.meta, assetToSell, diff --git a/src/raps/utils.ts b/src/raps/utils.ts index 5baebd0a5b9..284596be057 100644 --- a/src/raps/utils.ts +++ b/src/raps/utils.ts @@ -2,7 +2,7 @@ import { Block, Provider } from '@ethersproject/abstract-provider'; import { MaxUint256 } from '@ethersproject/constants'; import { Contract, PopulatedTransaction } from '@ethersproject/contracts'; import { StaticJsonRpcProvider } from '@ethersproject/providers'; -import { ALLOWS_PERMIT, CrosschainQuote, Quote, getQuoteExecutionDetails, getRainbowRouterContractAddress } from '@rainbow-me/swaps'; +import { CrosschainQuote, Quote, getQuoteExecutionDetails, getRainbowRouterContractAddress } from '@rainbow-me/swaps'; import { mainnet } from 'viem/chains'; import { Chain, erc20Abi } from 'viem'; import { GasFeeParamsBySpeed, LegacyGasFeeParamsBySpeed, LegacyTransactionGasParamAmounts, TransactionGasParamAmounts } from '@/entities'; @@ -140,14 +140,7 @@ const getClosestGasEstimate = async (estimationFn: (gasEstimate: number) => Prom }; export const getDefaultGasLimitForTrade = (quote: Quote, chainId: Chain['id']): string => { - const allowsPermit = chainId === mainnet.id && ALLOWS_PERMIT[quote?.sellTokenAddress?.toLowerCase()]; - - let defaultGasLimit = quote?.defaultGasLimit; - - if (allowsPermit) { - defaultGasLimit = Math.max(Number(defaultGasLimit), Number(multiply(gasUnits.basic_swap_permit, EXTRA_GAS_PADDING))).toString(); - } - return defaultGasLimit || multiply(gasUnits.basic_swap[chainId], EXTRA_GAS_PADDING); + return quote?.defaultGasLimit || multiply(gasUnits.basic_swap[chainId], EXTRA_GAS_PADDING); }; export const estimateSwapGasLimitWithFakeApproval = async (