From 1745ea60e2fd27d021765938e55cc7d8ce95b684 Mon Sep 17 00:00:00 2001 From: Pedro Yves Fracari Date: Fri, 8 Nov 2024 12:04:34 -0300 Subject: [PATCH] fix: infinite load on order change --- .../hooks/useTenderlyBundleSimulation.ts | 146 +++++++++--------- .../tenderly/utils/bundleSimulation.ts | 15 +- 2 files changed, 84 insertions(+), 77 deletions(-) diff --git a/apps/cowswap-frontend/src/modules/tenderly/hooks/useTenderlyBundleSimulation.ts b/apps/cowswap-frontend/src/modules/tenderly/hooks/useTenderlyBundleSimulation.ts index bf6e0bfa68..9749c0e8f9 100644 --- a/apps/cowswap-frontend/src/modules/tenderly/hooks/useTenderlyBundleSimulation.ts +++ b/apps/cowswap-frontend/src/modules/tenderly/hooks/useTenderlyBundleSimulation.ts @@ -1,4 +1,4 @@ -import { useCallback, useMemo } from 'react' +import { useCallback } from 'react' import { CowHookDetails } from '@cowprotocol/hook-dapp-lib' import { useWalletInfo } from '@cowprotocol/wallet' @@ -8,107 +8,111 @@ import useSWR from 'swr' import { useHooks } from 'modules/hooksStore' import { useOrderParams } from 'modules/hooksStore/hooks/useOrderParams' -import { useTokenContract } from 'common/hooks/useContract' - import { useGetTopTokenHolders } from './useGetTopTokenHolders' import { completeBundleSimulation, hooksBundleSimulation } from '../utils/bundleSimulation' import { generateNewSimulationData, generateSimulationDataToError } from '../utils/generateSimulationData' import { getTokenTransferInfo } from '../utils/getTokenTransferInfo' +type BundleSimulationSwrParams = { + preHooks: CowHookDetails[] + postHooks: CowHookDetails[] +} + export function useTenderlyBundleSimulation() { const { account, chainId } = useWalletInfo() const { preHooks, postHooks } = useHooks() const orderParams = useOrderParams() - const tokenSell = useTokenContract(orderParams?.sellTokenAddress) - const tokenBuy = useTokenContract(orderParams?.buyTokenAddress) - const buyAmount = orderParams?.buyAmount - const sellAmount = orderParams?.sellAmount - const orderReceiver = orderParams?.receiver || account const getTopTokenHolder = useGetTopTokenHolders() - const isOrderComplete = useMemo(() => { - return !!account && !!tokenBuy && !!tokenSell && !!buyAmount && !!sellAmount && !!orderReceiver - }, [account, tokenBuy, tokenSell, buyAmount, sellAmount, orderReceiver]) - - const simulateBundle = useCallback(async () => { - if (postHooks.length === 0 && preHooks.length === 0) return + const simulateBundle = useCallback( + async ({ preHooks, postHooks }: BundleSimulationSwrParams) => { + if (postHooks.length === 0 && preHooks.length === 0) return + + if (!postHooks.length) + return hooksBundleSimulation({ + chainId, + preHooks, + postHooks: [], + }) + + if ( + !account || + !orderParams?.buyTokenAddress || + !orderParams?.sellTokenAddress || + !orderParams?.buyAmount || + !orderParams?.sellAmount || + !orderParams?.receiver + ) { + return hooksBundleSimulation({ + chainId, + preHooks, + postHooks, + }) + } - if (!postHooks.length) - return hooksBundleSimulation({ + const buyTokenTopHolders = await getTopTokenHolder({ + tokenAddress: orderParams.buyTokenAddress, chainId, - preHooks, - postHooks: [], }) - if (!account || !tokenBuy || !tokenSell || !buyAmount || !sellAmount || !orderReceiver) { - return hooksBundleSimulation({ - chainId, - preHooks, - postHooks, + if (!buyTokenTopHolders) return + + const tokenBuyTransferInfo = getTokenTransferInfo({ + tokenHolders: buyTokenTopHolders, + amountToTransfer: orderParams.buyAmount, }) - } - - const buyTokenTopHolders = await getTopTokenHolder({ - tokenAddress: tokenBuy.address, - chainId, - }) - - if (!buyTokenTopHolders) return - - const tokenBuyTransferInfo = getTokenTransferInfo({ - tokenHolders: buyTokenTopHolders, - amountToTransfer: buyAmount, - }) - - const paramsComplete = { - postHooks, - preHooks, - tokenBuy, - tokenBuyTransferInfo, - sellAmount, - orderReceiver, - tokenSell, - account, - chainId, - } - - return completeBundleSimulation(paramsComplete) - }, [ - account, - chainId, - getTopTokenHolder, - tokenBuy, - postHooks, - preHooks, - buyAmount, - sellAmount, - orderReceiver, - tokenSell, - ]) + + const paramsComplete = { + postHooks, + preHooks, + tokenBuy: orderParams.buyTokenAddress, + tokenBuyTransferInfo, + sellAmount: orderParams.sellAmount, + buyAmount: orderParams.buyAmount, + orderReceiver: orderParams.receiver, + tokenSell: orderParams.sellTokenAddress, + account, + chainId, + } + + return completeBundleSimulation(paramsComplete) + }, + [account, chainId, getTopTokenHolder, orderParams], + ) const getNewSimulationData = useCallback( - async ([_, preHooks, postHooks, _isOrderComplete]: [string, CowHookDetails[], CowHookDetails[], boolean]) => { - const simulationData = await simulateBundle() + async ([_, params]: [string, BundleSimulationSwrParams]) => { + const simulationData = await simulateBundle(params) if (!simulationData) { return {} } try { - return generateNewSimulationData(simulationData, { preHooks, postHooks }) + return generateNewSimulationData(simulationData, { preHooks: params.preHooks, postHooks: params.postHooks }) } catch (e) { console.log(`error`, { e, simulationData }) - return generateSimulationDataToError({ preHooks, postHooks }) + return generateSimulationDataToError({ preHooks: params.preHooks, postHooks: params.postHooks }) } }, [simulateBundle], ) - return useSWR(['tenderly-bundle-simulation', preHooks, postHooks, isOrderComplete], getNewSimulationData, { - revalidateOnFocus: false, - revalidateOnReconnect: false, - refreshWhenOffline: false, - }) + return useSWR( + [ + 'tenderly-bundle-simulation', + { + preHooks, + postHooks, + }, + ], + getNewSimulationData, + { + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + }, + ) } diff --git a/apps/cowswap-frontend/src/modules/tenderly/utils/bundleSimulation.ts b/apps/cowswap-frontend/src/modules/tenderly/utils/bundleSimulation.ts index ea6f50e751..2606308869 100644 --- a/apps/cowswap-frontend/src/modules/tenderly/utils/bundleSimulation.ts +++ b/apps/cowswap-frontend/src/modules/tenderly/utils/bundleSimulation.ts @@ -1,17 +1,20 @@ -import { Erc20 } from '@cowprotocol/abis' +import { Erc20Abi } from '@cowprotocol/abis' import { BFF_BASE_URL } from '@cowprotocol/common-const' import { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS, SupportedChainId } from '@cowprotocol/cow-sdk' import { CowHookDetails } from '@cowprotocol/hook-dapp-lib' +import { Interface } from 'ethers/lib/utils' + import { CowHook } from 'modules/hooksStore/types/hooks' import { SimulationData, SimulationInput } from '../types' +const erc20Interface = new Interface(Erc20Abi) export interface GetTransferTenderlySimulationInput { currencyAmount: string from: string receiver: string - token: Erc20 + token: string } export type TokenBuyTransferInfo = { @@ -21,8 +24,8 @@ export type TokenBuyTransferInfo = { export interface PostBundleSimulationParams { account: string chainId: SupportedChainId - tokenSell: Erc20 - tokenBuy: Erc20 + tokenSell: string + tokenBuy: string preHooks: CowHookDetails[] postHooks: CowHookDetails[] sellAmount: string @@ -71,11 +74,11 @@ export function getTransferTenderlySimulationInput({ receiver, token, }: GetTransferTenderlySimulationInput): SimulationInput { - const callData = token.interface.encodeFunctionData('transfer', [receiver, currencyAmount]) + const callData = erc20Interface.encodeFunctionData('transfer', [receiver, currencyAmount]) return { input: callData, - to: token.address, + to: token, from, } }