From c7b49deb0f4d5a99c092cba31e28ab133ec35f70 Mon Sep 17 00:00:00 2001 From: willpote <81638931+willpote@users.noreply.github.com> Date: Fri, 5 Aug 2022 23:03:16 +0100 Subject: [PATCH] feat: Adjust gas estimates for auto slippage (#4213) * refactor: Adjust gas estimates for auto slippage * TODO for interleaved routes * pr feedback --- src/hooks/useAutoSlippageTolerance.ts | 35 ++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/hooks/useAutoSlippageTolerance.ts b/src/hooks/useAutoSlippageTolerance.ts index a6ca0ca728..f89e26b800 100644 --- a/src/hooks/useAutoSlippageTolerance.ts +++ b/src/hooks/useAutoSlippageTolerance.ts @@ -1,4 +1,4 @@ -import { Trade } from '@uniswap/router-sdk' +import { Protocol, Trade } from '@uniswap/router-sdk' import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core' import { useWeb3React } from '@web3-react/core' import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains' @@ -14,14 +14,41 @@ import useStablecoinPrice, { useStablecoinValue } from './useStablecoinPrice' const V3_SWAP_DEFAULT_SLIPPAGE = new Percent(50, 10_000) // .50% const ONE_TENTHS_PERCENT = new Percent(10, 10_000) // .10% export const DEFAULT_AUTO_SLIPPAGE = ONE_TENTHS_PERCENT +const GAS_ESTIMATE_BUFFER = new Percent(10, 100) // 10% + +// Base costs regardless of how many hops in the route +const V3_SWAP_BASE_GAS_ESTIMATE = 100_000 +const V2_SWAP_BASE_GAS_ESTIMATE = 135_000 + +// Extra cost per hop in the route +const V3_SWAP_HOP_GAS_ESTIMATE = 70_000 +const V2_SWAP_HOP_GAS_ESTIMATE = 50_000 /** * Return a guess of the gas cost used in computing slippage tolerance for a given trade * @param trade the trade for which to _guess_ the amount of gas it would cost to execute + * + * V3 logic is inspired by: + * https://github.com/Uniswap/smart-order-router/blob/main/src/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.ts + * V2 logic is inspired by: + * https://github.com/Uniswap/smart-order-router/blob/main/src/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.ts */ function guesstimateGas(trade: Trade | undefined): number | undefined { if (!!trade) { - return 100_000 + trade.swaps.reduce((memo, swap) => swap.route.pools.length + memo, 0) * 30_000 + let gas = 0 + for (const { route } of trade.swaps) { + if (route.protocol === Protocol.V2) { + gas += V2_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V2_SWAP_HOP_GAS_ESTIMATE + } else if (route.protocol === Protocol.V3) { + // V3 gas costs scale on initialized ticks being crossed, but we don't have that data here. + // We bake in some tick crossings into the base 100k cost. + gas += V3_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V3_SWAP_HOP_GAS_ESTIMATE + } else { + // TODO: Update with better estimates once we have interleaved routes. + gas += V3_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V3_SWAP_HOP_GAS_ESTIMATE + } + } + return gas } return undefined } @@ -61,8 +88,8 @@ export default function useAutoSlippageTolerance( // if not, use local heuristic const dollarCostToUse = chainId && SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId) && trade?.gasUseEstimateUSD - ? trade.gasUseEstimateUSD - : dollarGasCost + ? trade.gasUseEstimateUSD.multiply(GAS_ESTIMATE_BUFFER) + : dollarGasCost?.multiply(GAS_ESTIMATE_BUFFER) if (outputDollarValue && dollarCostToUse) { // the rationale is that a user will not want their trade to fail for a loss due to slippage that is less than