Skip to content

Commit

Permalink
feat(hackathon-surplus): do not show modal when too small amounts (#2857
Browse files Browse the repository at this point in the history
)

* chore: export and move isParsedOrder to parseOrder utils

* chore: add constants to control surplus modal display

* refactor: update types to use Nullish

* feat: return showSurplus from useGetSurplusData

* chore: do not render surplus modal if it shouldn't

* chore: move showSurplus to parent

* feat: do not show surplus modal on confirmation modal when it shouldn't

* feat: do not show independent surplus modal when it shouldn't

* chore: remove debug logs
  • Loading branch information
alfetopito authored Jul 12, 2023
1 parent f48e892 commit 6a5fa72
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 28 deletions.
34 changes: 28 additions & 6 deletions src/common/hooks/useGetSurplusFiatValue.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { useMemo } from 'react'

import { Token, CurrencyAmount } from '@uniswap/sdk-core'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'

import { MIN_FIAT_SURPLUS_VALUE } from 'legacy/constants'
import { Nullish } from 'types'

import { MIN_FIAT_SURPLUS_VALUE, MIN_FIAT_SURPLUS_VALUE_MODAL, MIN_SURPLUS_UNITS } from 'legacy/constants'
import { useCoingeckoUsdValue } from 'legacy/hooks/useStablecoinPrice'
import { Order } from 'legacy/state/orders/actions'

import { getExecutedSummaryData } from 'utils/getExecutedSummaryData'
import { ParsedOrder } from 'utils/orderUtils/parseOrder'

type Output = {
surplusFiatValue: CurrencyAmount<Token> | null
surplusAmount: CurrencyAmount<Token> | undefined
surplusToken: Token | undefined
surplusFiatValue: Nullish<CurrencyAmount<Currency>>
surplusAmount: Nullish<CurrencyAmount<Currency>>
surplusToken: Nullish<Currency>
showFiatValue: boolean
showSurplus: boolean | null
}

export function useGetSurplusData(order: Order | ParsedOrder | undefined): Output {
const { surplusAmount, surplusToken } = useMemo(() => {
const output: { surplusToken?: Token; surplusAmount?: CurrencyAmount<Token> } = {}
const output: { surplusToken?: Currency; surplusAmount?: CurrencyAmount<Currency> } = {}

if (order) {
const summaryData = getExecutedSummaryData(order)
Expand All @@ -33,10 +36,29 @@ export function useGetSurplusData(order: Order | ParsedOrder | undefined): Outpu
const surplusFiatValue = useCoingeckoUsdValue(surplusAmount)
const showFiatValue = Number(surplusFiatValue?.toExact()) >= MIN_FIAT_SURPLUS_VALUE

const showSurplus = shouldShowSurplus(surplusFiatValue, surplusAmount)

return {
surplusFiatValue,
showFiatValue,
surplusToken,
surplusAmount,
showSurplus,
}
}

function shouldShowSurplus(
fiatAmount: Nullish<CurrencyAmount<Currency>>,
surplusAmount: Nullish<CurrencyAmount<Currency>>
): boolean | null {
if (fiatAmount) {
// When there's a fiat amount, use that to decide whether to display the modal
return Number(fiatAmount.toFixed(3)) > MIN_FIAT_SURPLUS_VALUE_MODAL
} else if (surplusAmount) {
// If no fiat value, check whether surplus units are > MIN_SURPLUS_UNITS
return Number(surplusAmount.toFixed(3)) > MIN_SURPLUS_UNITS
}

// Otherwise, we don't know whether surplus should, return `null` to indicate that
return null
}
4 changes: 2 additions & 2 deletions src/common/pure/TransactionSubmittedContent/SurplusModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export type SurplusModalProps = {
export function SurplusModal(props: SurplusModalProps) {
const { order } = props

const { surplusFiatValue, showFiatValue, surplusToken, surplusAmount } = useGetSurplusData(order)
const { surplusFiatValue, showFiatValue, surplusToken, surplusAmount, showSurplus } = useGetSurplusData(order)

const onTweetShare = useCallback(() => {
sendEvent({
Expand All @@ -159,7 +159,7 @@ export function SurplusModal(props: SurplusModalProps) {
})
}, [])

if (!order) {
if (!order || !showSurplus) {
return null
}

Expand Down
7 changes: 3 additions & 4 deletions src/common/pure/TransactionSubmittedContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface TransactionSubmittedContentProps {
chainId: ChainId
activityDerivedState: ActivityDerivedState | null
currencyToAdd?: Nullish<Currency>
showSurplus?: boolean | null
}

export function TransactionSubmittedContent({
Expand All @@ -55,11 +56,11 @@ export function TransactionSubmittedContent({
hash,
currencyToAdd,
activityDerivedState,
showSurplus,
}: TransactionSubmittedContentProps) {
const activityState = activityDerivedState && getActivityState(activityDerivedState)
const showProgressBar = activityState === 'open' || activityState === 'filled'
const { order } = activityDerivedState || {}
const showSurplus = activityState === 'filled'

if (!supportedChainId(chainId)) {
return null
Expand All @@ -71,9 +72,7 @@ export function TransactionSubmittedContent({
<styledEl.Header>
<styledEl.CloseIconWrapper onClick={onDismiss} />
</styledEl.Header>
{showSurplus ? (
<SurplusModal order={order} />
) : (
{(showSurplus && <SurplusModal order={order} />) || (
<>
<Text fontWeight={600} fontSize={28}>
{getTitleStatus(activityDerivedState)}
Expand Down
16 changes: 10 additions & 6 deletions src/legacy/components/TransactionConfirmationModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { getActivityState, useActivityDerivedState } from 'legacy/hooks/useActiv
import { useMultipleActivityDescriptors } from 'legacy/hooks/useRecentActivity'
import { handleFollowPendingTxPopupAtom, useUpdateAtom } from 'legacy/state/application/atoms'

import { ActivityDerivedState } from 'modules/account/containers/Transaction'
import { setIsConfirmationModalOpenAtom } from 'modules/swap/state/surplusModal'
import { useSetIsConfirmationModalOpen } from 'modules/swap/state/surplusModal'
import { useWalletInfo } from 'modules/wallet'

import { useGetSurplusData } from 'common/hooks/useGetSurplusFiatValue'
import { CowModal } from 'common/pure/Modal'
import { TransactionSubmittedContent } from 'common/pure/TransactionSubmittedContent'

Expand Down Expand Up @@ -43,8 +43,11 @@ export function TransactionConfirmationModal({
const setShowFollowPendingTxPopup = useUpdateAtom(handleFollowPendingTxPopupAtom)
const activities = useMultipleActivityDescriptors({ chainId, ids: [hash || ''] }) || []
const activityDerivedState = useActivityDerivedState({ chainId, activity: activities[0] })
const { showSurplus: canShowSurplus } = useGetSurplusData(activityDerivedState?.order)

const setIsConfirmationModalOpen = useUpdateAtom(setIsConfirmationModalOpenAtom)
const showSurplus = canShowSurplus && activityDerivedState && getActivityState(activityDerivedState) === 'filled'

const setIsConfirmationModalOpen = useSetIsConfirmationModalOpen()

useEffect(() => setIsConfirmationModalOpen(isOpen && !!hash), [hash, isOpen, setIsConfirmationModalOpen])

Expand All @@ -64,7 +67,7 @@ export function TransactionConfirmationModal({

if (!chainId) return null

const width = getWidth(hash, activityDerivedState)
const width = getWidth(hash, showSurplus)

return (
<CowModal isOpen={isOpen} onDismiss={_onDismiss} maxHeight={90} maxWidth={width}>
Expand All @@ -82,6 +85,7 @@ export function TransactionConfirmationModal({
activityDerivedState={activityDerivedState}
onDismiss={_onDismiss}
currencyToAdd={currencyToAdd}
showSurplus={showSurplus}
/>
) : (
content?.()
Expand All @@ -90,8 +94,8 @@ export function TransactionConfirmationModal({
)
}

function getWidth(hash: string | undefined, activityDerivedState: ActivityDerivedState | null): number {
if (activityDerivedState && getActivityState(activityDerivedState) === 'filled') {
function getWidth(hash: string | undefined, showSurplus: boolean | null): number {
if (showSurplus) {
return 470
}
if (hash) {
Expand Down
11 changes: 8 additions & 3 deletions src/legacy/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ethFlowBarnJson, ethFlowProdJson } from '@cowprotocol/abis'
import networksJson from '@cowprotocol/contracts/networks.json'
import { IpfsConfig } from '@cowprotocol/cow-sdk'
import { SupportedChainId as ChainId } from '@cowprotocol/cow-sdk'
import { Token, Fraction, Percent } from '@uniswap/sdk-core'
import { IpfsConfig, SupportedChainId as ChainId } from '@cowprotocol/cow-sdk'
import { Fraction, Percent, Token } from '@uniswap/sdk-core'

import BigNumber from 'bignumber.js'
import ms from 'ms.macro'
Expand Down Expand Up @@ -211,3 +210,9 @@ export const FAQ_MENU_LINKS = [

// Min USD value to show surplus
export const MIN_FIAT_SURPLUS_VALUE = 0.01

// Min FIAT value for displaying the surplus modal
export const MIN_FIAT_SURPLUS_VALUE_MODAL = 1

// Min surplus value in units for displaying the surplus modal when FIAT value is not available
export const MIN_SURPLUS_UNITS = 0.1
13 changes: 11 additions & 2 deletions src/modules/swap/containers/SurplusModalSetup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useCallback } from 'react'
import { useCallback, useEffect } from 'react'

import { useOrder } from 'legacy/state/orders/hooks'

import { useWalletInfo } from 'modules/wallet'

import { useGetSurplusData } from 'common/hooks/useGetSurplusFiatValue'
import { CowModal } from 'common/pure/Modal'
import * as styledEl from 'common/pure/TransactionSubmittedContent/styled'
import { SurplusModal } from 'common/pure/TransactionSubmittedContent/SurplusModal'
Expand All @@ -16,12 +17,20 @@ export function SurplusModalSetup() {

const { chainId } = useWalletInfo()
const order = useOrder({ id: orderId, chainId })
const { showSurplus } = useGetSurplusData(order)

const onDismiss = useCallback(() => {
orderId && removeOrderId(orderId)
}, [orderId, removeOrderId])

const isOpen = !!orderId
useEffect(() => {
// If we should NOT show the surplus, remove the orderId from the queue
if (showSurplus === false && orderId) {
removeOrderId(orderId)
}
}, [orderId, removeOrderId, showSurplus])

const isOpen = !!orderId && showSurplus === true

return (
<CowModal isOpen={isOpen} onDismiss={onDismiss} maxHeight={90} maxWidth={470}>
Expand Down
6 changes: 1 addition & 5 deletions src/utils/getExecutedSummaryData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import { Order } from 'legacy/state/orders/actions'

import { getFilledAmounts } from 'utils/orderUtils/getFilledAmounts'

import { ParsedOrder, parseOrder } from './orderUtils/parseOrder'

function isParsedOrder(order: Order | ParsedOrder): order is ParsedOrder {
return !!(order as ParsedOrder).executionData
}
import { isParsedOrder, ParsedOrder, parseOrder } from './orderUtils/parseOrder'

export function getExecutedSummaryData(order: Order | ParsedOrder) {
const parsedOrder = isParsedOrder(order) ? order : parseOrder(order)
Expand Down
4 changes: 4 additions & 0 deletions src/utils/orderUtils/parseOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,7 @@ export const parseOrder = (order: Order): ParsedOrder => {
executionData,
}
}

export function isParsedOrder(order: Order | ParsedOrder): order is ParsedOrder {
return !!(order as ParsedOrder).executionData
}

0 comments on commit 6a5fa72

Please sign in to comment.