diff --git a/.mergify.yml b/.mergify.yml index ef80e1752..573464a46 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,3 +1,9 @@ +queue_rules: + - name: default + conditions: + - check-success=Deploy + - check-success=Cypress + pull_request_rules: - name: Merge approved and green PRs when tagged with 'Auto-merge' conditions: @@ -6,10 +12,11 @@ pull_request_rules: - check-success=Deploy - check-success=Cypress actions: - merge: + queue: method: squash - strict: smart+fasttrack + name: default commit_message: title+body + # DEPENDABOT PRs - name: automatic merge for Dependabot pull requests conditions: - author~=^dependabot(|-preview)\[bot\]$ @@ -18,7 +25,7 @@ pull_request_rules: - check-success=Deploy - base=develop actions: - merge: + queue: method: squash - strict: smart+fasttrack + name: default commit_message: title+body diff --git a/package.json b/package.json index 4ea029e85..b7229bddc 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "CowSwap - Gnosis Protocol", "homepage": ".", "private": true, - "version": "1.6.0", + "version": "1.7.0-rc.0", "engines": { "node": ">=14.0.0" }, diff --git a/src/custom/hooks/useUSDCPrice/index.ts b/src/custom/hooks/useUSDCPrice/index.ts index 66a3ad288..c166e5fd4 100644 --- a/src/custom/hooks/useUSDCPrice/index.ts +++ b/src/custom/hooks/useUSDCPrice/index.ts @@ -1,5 +1,5 @@ import { CurrencyAmount, Currency, Price, Token } from '@uniswap/sdk-core' -import { useEffect, useMemo, useState } from 'react' +import { useEffect, useMemo, useRef, useState } from 'react' import { SupportedChainId } from 'constants/chains' /* import { DAI_OPTIMISM, USDC, USDC_ARBITRUM } from '../constants/tokens' import { useV2TradeExactOut } from './useV2Trade' @@ -167,62 +167,67 @@ export function useCoingeckoUsdPrice(currency?: Currency) { const [price, setPrice] = useState | null>(null) const [error, setError] = useState(null) - useEffect(() => { - const isSupportedChainId = supportedChainId(chainId) - if (!isSupportedChainId || !currency) return + // Currency is deep nested and we only really care about token address changing + // so we ref it here as to avoid updating useEffect + const currencyRef = useRef(currency) + currencyRef.current = currency - const baseAmount = tryParseAmount('1', currency) - const tokenAddress = currencyId(currency) + const tokenAddress = currencyRef.current ? currencyId(currencyRef.current) : undefined - if (baseAmount) { - getUSDPriceQuote({ - chainId: isSupportedChainId, - tokenAddress, + useEffect(() => { + const isSupportedChainId = supportedChainId(chainId) + const baseAmount = tryParseAmount('1', currencyRef.current) + + if (!isSupportedChainId || !tokenAddress || !baseAmount) return + + getUSDPriceQuote({ + chainId: isSupportedChainId, + tokenAddress, + }) + .then(toPriceInformation) + .then((priceResponse) => { + setError(null) + + if (!priceResponse?.amount) return + + const { amount: apiUsdPrice } = priceResponse + // api returns converted units e.g $2.25 instead of 2255231233312312 (atoms) + // we need to parse all USD returned amounts + // and convert to the same currencyRef.current for both sides (SDK math invariant) + // in our case we stick to the USDC paradigm + const quoteAmount = tryParseAmount(apiUsdPrice.toString(), USDC) + // parse failure is unlikely - type safe + if (!quoteAmount) return + // create a new Price object + // we need to invert here as it is + // constructed based on the coingecko USD price response + // e.g 1 unit of USER'S TOKEN represented in USD + const usdPrice = new Price({ + baseAmount, + quoteAmount, + }).invert() + + console.debug( + '[useCoingeckoUsdPrice] Best Coingecko USD price amount', + usdPrice.toSignificant(12), + usdPrice.invert().toSignificant(12) + ) + + return setPrice(usdPrice) }) - .then(toPriceInformation) - .then((priceResponse) => { - setError(null) - - if (!priceResponse?.amount) return - - const { amount: apiUsdPrice } = priceResponse - // api returns converted units e.g $2.25 instead of 2255231233312312 (atoms) - // we need to parse all USD returned amounts - // and convert to the same currency for both sides (SDK math invariant) - // in our case we stick to the USDC paradigm - const quoteAmount = tryParseAmount(apiUsdPrice.toString(), USDC) - // parse failure is unlikely - type safe - if (!quoteAmount) return - // create a new Price object - // we need to invert here as it is - // constructed based on the coingecko USD price response - // e.g 1 unit of USER'S TOKEN represented in USD - const usdPrice = new Price({ - baseAmount, - quoteAmount, - }).invert() - - console.debug( - '[useCoingeckoUsdPrice] Best Coingecko USD price amount', - usdPrice.toSignificant(12), - usdPrice.invert().toSignificant(12) - ) - - return setPrice(usdPrice) + .catch((error) => { + console.error( + '[useUSDCPrice::useCoingeckoUsdPrice]::Error getting USD price from Coingecko for token', + tokenAddress, + error + ) + return batchedUpdate(() => { + setError(new Error(error)) + setPrice(null) }) - .catch((error) => { - console.error( - '[useUSDCPrice::useCoingeckoUsdPrice]::Error getting USD price from Coingecko for token', - currency.symbol, - error - ) - return batchedUpdate(() => { - setError(new Error(error)) - setPrice(null) - }) - }) - } - }, [chainId, currency, blockNumber]) + }) + // don't depend on Currency (deep nested object) + }, [chainId, blockNumber, tokenAddress]) return { price, error } } @@ -234,26 +239,8 @@ export function useCoingeckoUsdValue(currencyAmount: CurrencyAmount | } export function useHigherUSDValue(currencyAmount: CurrencyAmount | undefined) { - const usdcValue = useUSDCValue(currencyAmount) + const gpUsdPrice = useUSDCValue(currencyAmount) const coingeckoUsdPrice = useCoingeckoUsdValue(currencyAmount) - return useMemo(() => { - // USDC PRICE UNAVAILABLE - if (!usdcValue && coingeckoUsdPrice) { - console.debug('[USD Estimation]::COINGECKO') - return coingeckoUsdPrice - // COINGECKO PRICE UNAVAILABLE - } else if (usdcValue && !coingeckoUsdPrice) { - console.debug('[USD Estimation]::UNIv2') - return usdcValue - // BOTH AVAILABLE - } else if (usdcValue && coingeckoUsdPrice) { - console.debug('[USD Estimation]::[BOTH] ==> COIN') - // coingecko logic takes precedence - return coingeckoUsdPrice - } else { - console.debug('[USD Estimation]::None found') - return null - } - }, [usdcValue, coingeckoUsdPrice]) + return coingeckoUsdPrice || gpUsdPrice } diff --git a/src/custom/pages/Swap/SwapMod.tsx b/src/custom/pages/Swap/SwapMod.tsx index 7b516563f..8c0354e66 100644 --- a/src/custom/pages/Swap/SwapMod.tsx +++ b/src/custom/pages/Swap/SwapMod.tsx @@ -76,7 +76,7 @@ import { computeSlippageAdjustedAmounts } from 'utils/prices' import FeeInformationTooltip from 'components/swap/FeeInformationTooltip' import { useWalletInfo } from 'hooks/useWalletInfo' import { HashLink } from 'react-router-hash-link' -import { logTradeDetails } from 'state/swap/utils' +// import { logTradeDetails } from 'state/swap/utils' import { useGetQuoteAndStatus } from 'state/price/hooks' import { SwapProps, ButtonError, ButtonPrimary } from '.' // mod import TradeGp from 'state/swap/TradeGp' @@ -189,7 +189,7 @@ export default function Swap({ const { quote, isGettingNewQuote } = useGetQuoteAndStatus({ token: INPUT.currencyId, chainId }) // Log all trade information - logTradeDetails(v2Trade, allowedSlippage) + // logTradeDetails(v2Trade, allowedSlippage) // Checks if either currency is native ETH // MOD: adds this hook