Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: confirm calculation accuracy in tx panel #2137

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 5 additions & 29 deletions packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
41 changes: 27 additions & 14 deletions packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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'}`
}

/**
Expand All @@ -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'

Expand All @@ -144,9 +150,16 @@ export function getConfirmationTime(chainId: number) {
if (fastWithdrawalActive) {
confirmationTimeInSeconds = fastWithdrawalTime / 1000
} else {
confirmationTimeInSeconds = isTestnet
? DEFAULT_TESTNET_CONFIRMATION_TIME
: DEFAULT_CONFIRMATION_TIME
// Calculate confirmation period using block time from root chain:
// - Ethereum mainnet for Arbitrum chains
// - Parent chain for Base chains
const blockNumberReferenceChainId = getBlockNumberReferenceChainIdByChainId(
{ chainId }
)
confirmationTimeInSeconds =
getL1BlockTime(blockNumberReferenceChainId) *
getConfirmPeriodBlocks(chainId) +
CONFIRMATION_BUFFER_MINUTES * SECONDS_IN_MINUTE
}

const confirmationTimeInReadableFormat = formatDuration(
Expand Down
Loading