From 1b3b3a6aed0dad2c0d82e4d1b759d6b63571398f Mon Sep 17 00:00:00 2001 From: Doug Lance <4741454+douglance@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:30:34 -0500 Subject: [PATCH 1/2] fix: confirm calculation accuracy in tx panel --- .../src/hooks/useTransferDuration.ts | 34 +++------------- .../src/util/WithdrawalUtils.ts | 40 ++++++++++++------- 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts b/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts index f8671e23e2..ceb92a04c5 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts @@ -3,12 +3,7 @@ import { isValidTeleportChainPair } from '@/token-bridge-sdk/teleport' import { MergedTransaction } from '../state/app/state' import { useRemainingTimeCctp } from '../state/cctpState' -import { - getBlockNumberReferenceChainIdByChainId, - getConfirmPeriodBlocks, - getL1BlockTime, - isNetwork -} from '../util/networks' +import { isNetwork } from '../util/networks' import { getConfirmationTime } from '../util/WithdrawalUtils' const DEPOSIT_TIME_MINUTES = { @@ -31,13 +26,6 @@ const DEPOSIT_TIME_MINUTES_ORBIT = { testnet: 1 } -/** - * Buffer for after a node is confirmable but isn't yet confirmed. - * A rollup block (RBlock) typically gets asserted every 30-60 minutes. - */ -const CONFIRMATION_BUFFER_MINUTES = 60 -const SECONDS_IN_MIN = 60 - type UseTransferDurationResult = { approximateDurationInMinutes: number estimatedMinutesLeft: number | null @@ -122,22 +110,10 @@ export function getWithdrawalConfirmationDate({ // For new txs createdAt won't be defined yet, we default to the current time in that case const createdAtDate = createdAt ? dayjs(createdAt) : dayjs() - const { confirmationTimeInSeconds, fastWithdrawalActive } = - getConfirmationTime(withdrawalFromChainId) - if (fastWithdrawalActive && confirmationTimeInSeconds) { - return createdAtDate.add(confirmationTimeInSeconds, 'second') - } - - const blockNumberReferenceChainId = getBlockNumberReferenceChainIdByChainId({ - chainId: withdrawalFromChainId - }) - // the block time is always base chain's block time regardless of withdrawing from L3 to L2 or from L2 to L1 - // and similarly, the confirm period blocks is always the number of blocks on the base chain - const confirmationSeconds = - getL1BlockTime(blockNumberReferenceChainId) * - getConfirmPeriodBlocks(withdrawalFromChainId) + - CONFIRMATION_BUFFER_MINUTES * SECONDS_IN_MIN - return createdAtDate.add(confirmationSeconds, 'second') + const { confirmationTimeInSeconds } = getConfirmationTime( + withdrawalFromChainId + ) + return createdAtDate.add(confirmationTimeInSeconds, 'second') } function getWithdrawalDuration(tx: MergedTransaction) { diff --git a/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts b/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts index ac29f2c02c..17bf6596b7 100644 --- a/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts +++ b/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts @@ -10,8 +10,11 @@ import { GasEstimates } from '../hooks/arbTokenBridge.types' import { Address } from './AddressUtils' import { captureSentryErrorWithExtraData } from './SentryUtils' import { getBridgeUiConfigForChain } from './bridgeUiConfig' -import { isNetwork } from './networks' - +import { + getBlockNumberReferenceChainIdByChainId, + getConfirmPeriodBlocks, + getL1BlockTime +} from './networks' export async function withdrawInitTxEstimateGas({ amount, address, @@ -111,22 +114,26 @@ export async function withdrawInitTxEstimateGas({ const SECONDS_IN_MINUTE = 60 const SECONDS_IN_HOUR = 3600 const SECONDS_IN_DAY = 86400 -const DEFAULT_CONFIRMATION_TIME = 7 * SECONDS_IN_DAY -const DEFAULT_TESTNET_CONFIRMATION_TIME = SECONDS_IN_HOUR +/** + * Buffer for after a node is confirmable but isn't yet confirmed. + * A rollup block (RBlock) typically gets asserted every 30-60 minutes. + */ +const CONFIRMATION_BUFFER_MINUTES = 60 function formatDuration(seconds: number, short = false): string { if (seconds < SECONDS_IN_MINUTE) { - return `${seconds} ${short ? 'secs' : 'seconds'}` + return `${seconds} ${short ? 'secs' : seconds === 1 ? 'second' : 'seconds'}` } if (seconds < SECONDS_IN_HOUR) { - return `${Math.round(seconds / SECONDS_IN_MINUTE)} ${ - short ? 'mins' : 'minutes' - }` + const minutes = Math.round(seconds / SECONDS_IN_MINUTE) + return `${minutes} ${short ? 'mins' : minutes === 1 ? 'minute' : 'minutes'}` } if (seconds < SECONDS_IN_DAY) { - return `${Math.round(seconds / SECONDS_IN_HOUR)} hours` + const hours = Math.round(seconds / SECONDS_IN_HOUR) + return `${hours} ${hours === 1 ? 'hour' : 'hours'}` } - return `${Math.round(seconds / SECONDS_IN_DAY)} days` + const days = Math.round(seconds / SECONDS_IN_DAY) + return `${days} ${days === 1 ? 'day' : 'days'}` } /** @@ -135,7 +142,6 @@ function formatDuration(seconds: number, short = false): string { */ export function getConfirmationTime(chainId: number) { const { fastWithdrawalTime } = getBridgeUiConfigForChain(chainId) - const isTestnet = isNetwork(chainId).isTestnet const fastWithdrawalActive = typeof fastWithdrawalTime !== 'undefined' @@ -144,9 +150,15 @@ export function getConfirmationTime(chainId: number) { if (fastWithdrawalActive) { confirmationTimeInSeconds = fastWithdrawalTime / 1000 } else { - confirmationTimeInSeconds = isTestnet - ? DEFAULT_TESTNET_CONFIRMATION_TIME - : DEFAULT_CONFIRMATION_TIME + // the block time is always base chain's block time regardless of withdrawing from L3 to L2 or from L2 to L1 + // and similarly, the confirm period blocks is always the number of blocks on the base chain + const blockNumberReferenceChainId = getBlockNumberReferenceChainIdByChainId( + { chainId } + ) + confirmationTimeInSeconds = + getL1BlockTime(blockNumberReferenceChainId) * + getConfirmPeriodBlocks(chainId) + + CONFIRMATION_BUFFER_MINUTES * SECONDS_IN_MINUTE } const confirmationTimeInReadableFormat = formatDuration( From 2d40f71918a756f5d6208fbc11e150f94aac6243 Mon Sep 17 00:00:00 2001 From: Doug Lance <4741454+douglance@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:28:25 -0500 Subject: [PATCH 2/2] improve comment --- packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts b/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts index 17bf6596b7..7d14ef12e6 100644 --- a/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts +++ b/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts @@ -150,8 +150,9 @@ export function getConfirmationTime(chainId: number) { if (fastWithdrawalActive) { confirmationTimeInSeconds = fastWithdrawalTime / 1000 } else { - // the block time is always base chain's block time regardless of withdrawing from L3 to L2 or from L2 to L1 - // and similarly, the confirm period blocks is always the number of blocks on the base chain + // Calculate confirmation period using block time from root chain: + // - Ethereum mainnet for Arbitrum chains + // - Parent chain for Base chains const blockNumberReferenceChainId = getBlockNumberReferenceChainIdByChainId( { chainId } )