From 62531de05ed72e3466757de01184d4f3f5428c05 Mon Sep 17 00:00:00 2001 From: Jon Ator Date: Thu, 19 Sep 2024 11:40:34 -0400 Subject: [PATCH] Amplitude: prevent outlier value usd logs (#3825) * prevent outlier value usd logs * usd const * forgot one * format --- .../bridge/amount-and-review-screen.tsx | 18 ++++++++++--- packages/web/components/swap-tool/alt.tsx | 16 +++++++++--- packages/web/components/swap-tool/index.tsx | 16 +++++++++--- packages/web/config/analytics-events.ts | 6 ++--- .../web/hooks/limit-orders/use-place-limit.ts | 25 +++++++++++++++---- 5 files changed, 61 insertions(+), 20 deletions(-) diff --git a/packages/web/components/bridge/amount-and-review-screen.tsx b/packages/web/components/bridge/amount-and-review-screen.tsx index 733fb02a08..909d335854 100644 --- a/packages/web/components/bridge/amount-and-review-screen.tsx +++ b/packages/web/components/bridge/amount-and-review-screen.tsx @@ -6,7 +6,7 @@ import { useMemo, useState } from "react"; import { getAddress } from "viem"; import { Screen, useScreenManager } from "~/components/screen-manager"; -import { EventName } from "~/config"; +import { EventName, OUTLIER_USD_VALUE_THRESHOLD } from "~/config"; import { useAmplitudeAnalytics } from "~/hooks"; import { BridgeScreen } from "~/hooks/bridge"; import { useEvmWalletAccount } from "~/hooks/evm-wallet"; @@ -342,6 +342,18 @@ export const AmountAndReviewScreen = observer( ? fromChain.chainName : toChain.chainName; + let valueUsd = Number( + q.input.fiatValue.toDec().toString() + ); + // Protect our data from outliers + // Perhaps from upstream issues with price data providers + if ( + isNaN(valueUsd) || + valueUsd > OUTLIER_USD_VALUE_THRESHOLD + ) { + valueUsd = 0; + } + logEvent([ EventName.DepositWithdraw.started, { @@ -352,9 +364,7 @@ export const AmountAndReviewScreen = observer( isRecommendedVariant, network: networkName, transferDirection: direction, - valueUsd: Number( - q.input.fiatValue.toDec().toString() - ), + valueUsd, walletName, }, ]); diff --git a/packages/web/components/swap-tool/alt.tsx b/packages/web/components/swap-tool/alt.tsx index f3107e3e45..ec88970f45 100644 --- a/packages/web/components/swap-tool/alt.tsx +++ b/packages/web/components/swap-tool/alt.tsx @@ -29,7 +29,7 @@ import { tError } from "~/components/localization"; import { TradeDetails } from "~/components/swap-tool/trade-details"; import { GenericDisclaimer } from "~/components/tooltip/generic-disclaimer"; import { Button } from "~/components/ui/button"; -import { EventName, EventPage } from "~/config"; +import { EventName, EventPage, OUTLIER_USD_VALUE_THRESHOLD } from "~/config"; import { useAmplitudeAnalytics, useDisclosure, @@ -214,6 +214,16 @@ export const AltSwapTool: FunctionComponent = observer( const sendSwapTx = () => { if (!swapState.inAmountInput.amount) return; + let valueUsd = Number( + swapState.inAmountInput.fiatValue?.toDec().toString() ?? "0" + ); + + // Protect our data from outliers + // Perhaps from upstream issues with price data providers + if (isNaN(valueUsd) || valueUsd > OUTLIER_USD_VALUE_THRESHOLD) { + valueUsd = 0; + } + const baseEvent = { fromToken: swapState.fromAsset?.coinDenom, tokenAmount: Number(swapState.inAmountInput.amount.toDec().toString()), @@ -223,9 +233,7 @@ export const AltSwapTool: FunctionComponent = observer( ({ pools }) => pools.length !== 1 ), isMultiRoute: (swapState.quote?.split.length ?? 0) > 1, - valueUsd: Number( - swapState.inAmountInput.fiatValue?.toDec().toString() ?? "0" - ), + valueUsd, feeValueUsd: Number(swapState.totalFee?.toString() ?? "0"), page, quoteTimeMilliseconds: swapState.quote?.timeMs, diff --git a/packages/web/components/swap-tool/index.tsx b/packages/web/components/swap-tool/index.tsx index f1c009d0a2..e72e5897ab 100644 --- a/packages/web/components/swap-tool/index.tsx +++ b/packages/web/components/swap-tool/index.tsx @@ -28,7 +28,7 @@ import { Popover } from "~/components/popover"; import { SplitRoute } from "~/components/swap-tool/split-route"; import { InfoTooltip, Tooltip } from "~/components/tooltip"; import { Button } from "~/components/ui/button"; -import { EventName, EventPage } from "~/config"; +import { EventName, EventPage, OUTLIER_USD_VALUE_THRESHOLD } from "~/config"; import { useAmplitudeAnalytics, useDisclosure, @@ -186,6 +186,16 @@ export const SwapTool: FunctionComponent = observer( if (!swapState.inAmountInput.amount) return; + let valueUsd = Number( + swapState.inAmountInput.fiatValue?.toDec().toString() ?? "0" + ); + + // Protect our data from outliers + // Perhaps from upstream issues with price data providers + if (isNaN(valueUsd) || valueUsd > OUTLIER_USD_VALUE_THRESHOLD) { + valueUsd = 0; + } + const baseEvent = { fromToken: swapState.fromAsset?.coinDenom, tokenAmount: Number(swapState.inAmountInput.amount.toDec().toString()), @@ -195,9 +205,7 @@ export const SwapTool: FunctionComponent = observer( ({ pools }) => pools.length !== 1 ), isMultiRoute: (swapState.quote?.split.length ?? 0) > 1, - valueUsd: Number( - swapState.inAmountInput.fiatValue?.toDec().toString() ?? "0" - ), + valueUsd, feeValueUsd: Number(swapState.totalFee?.toString() ?? "0"), page, quoteTimeMilliseconds: swapState.quote?.timeMs, diff --git a/packages/web/config/analytics-events.ts b/packages/web/config/analytics-events.ts index ba6b1f92a1..28b5505fa4 100644 --- a/packages/web/config/analytics-events.ts +++ b/packages/web/config/analytics-events.ts @@ -1,11 +1,11 @@ /** # User Events Constants * Logged to Amplitude at https://analytics.amplitude.com/osmosis-zone/ */ - import { AllocationOptions } from "~/components/complex/portfolio/types"; -// Should be in sync with: https://docs.google.com/spreadsheets/d/18w8VwJmmRdb_E-XkE1UjkqhLxCyhqVVhWlzDgTtbRWo/edit?usp=sharing -// For maintainability - all event logs should be in high level component +/** Max value of USD event to check against to prevent + * outliers from corrupting dashboards. */ +export const OUTLIER_USD_VALUE_THRESHOLD = 1_500_000; export type AmountDefault = "half" | "max" | "input"; diff --git a/packages/web/hooks/limit-orders/use-place-limit.ts b/packages/web/hooks/limit-orders/use-place-limit.ts index 8d58e58991..7ddfcf1efd 100644 --- a/packages/web/hooks/limit-orders/use-place-limit.ts +++ b/packages/web/hooks/limit-orders/use-place-limit.ts @@ -6,7 +6,7 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { useAsync } from "react-use"; import { tError } from "~/components/localization"; -import { EventName, EventPage } from "~/config"; +import { EventName, EventPage, OUTLIER_USD_VALUE_THRESHOLD } from "~/config"; import { isValidNumericalRawInput, useAmountInput, @@ -283,6 +283,16 @@ export const usePlaceLimit = ({ } if (isMarket) { + let valueUsd = Number( + marketState.inAmountInput.fiatValue?.toDec().toString() ?? "0" + ); + + // Protect our data from outliers + // Perhaps from upstream issues with price data providers + if (isNaN(valueUsd) || valueUsd > OUTLIER_USD_VALUE_THRESHOLD) { + valueUsd = 0; + } + const baseEvent = { fromToken: marketState.fromAsset?.coinDenom, tokenAmount: Number( @@ -294,9 +304,7 @@ export const usePlaceLimit = ({ ({ pools }) => pools.length !== 1 ), isMultiRoute: (marketState.quote?.split.length ?? 0) > 1, - valueUsd: Number( - marketState.inAmountInput.fiatValue?.toDec().toString() ?? "0" - ), + valueUsd, feeValueUsd: Number(marketState.totalFee?.toString() ?? "0"), page, quoteTimeMilliseconds: marketState.quote?.timeMs, @@ -328,12 +336,19 @@ export const usePlaceLimit = ({ const paymentDenom = paymentTokenValue?.toCoin().denom ?? ""; + let valueUsd = Number(paymentFiatValue?.toDec().toString() ?? "0"); + // Protect our data from outliers + // Perhaps from upstream issues with price data providers + if (isNaN(valueUsd) || valueUsd > OUTLIER_USD_VALUE_THRESHOLD) { + valueUsd = 0; + } + const baseEvent = { type: orderDirection === "bid" ? "buy" : "sell", fromToken: paymentDenom, toToken: orderDirection === "bid" ? baseAsset?.coinDenom : quoteAsset?.coinDenom, - valueUsd: Number(paymentFiatValue?.toDec().toString() ?? "0"), + valueUsd, tokenAmount: Number(quantity), page, isOnHomePage: page === "Swap Page",