Skip to content

Commit

Permalink
Dev: master pull, conflcits
Browse files Browse the repository at this point in the history
  • Loading branch information
dewanshparashar committed Jun 11, 2024
2 parents 23cb44c + 58b5b8f commit 75d66c1
Show file tree
Hide file tree
Showing 17 changed files with 147 additions and 89 deletions.
1 change: 0 additions & 1 deletion .github/workflows/orbit-retryable-monitor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jobs:
uses: actions/checkout@v3
with:
repository: OffchainLabs/orbit-retryable-tracker
ref: 'enable-alerting' # the branch where our alerting code is present
path: orbit-retryable-tracker

- name: Copy chains JSON to Retryable-Tracker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { DepositCountdown } from '../common/DepositCountdown'
import { useRemainingTime } from '../../state/cctpState'
import { isDepositReadyToRedeem } from '../../state/app/utils'
import { Address } from '../../util/AddressUtils'
import { isTeleport } from '../../token-bridge-sdk/teleport'
import { isTeleport } from '@/token-bridge-sdk/teleport'
import {
firstRetryableLegRequiresRedeem,
secondRetryableLegForTeleportRequiresRedeem
Expand Down Expand Up @@ -173,6 +173,18 @@ const LastStepEndItem = ({
return null
}

export const TransactionFailedOnNetwork = ({
networkName
}: {
networkName: string
}) => (
<div>
Transaction failed on {networkName}. You have 7 days to try again. After
that, your funds will be{' '}
<span className="font-bold text-red-400">lost forever</span>.
</div>
)

export const TransactionsTableDetailsSteps = ({
tx,
address
Expand Down Expand Up @@ -210,13 +222,7 @@ export const TransactionsTableDetailsSteps = ({
}

if (isDepositReadyToRedeem(tx)) {
return (
<div>
Transaction failed on {networkName}. You have 7 days to try again.
After that, your funds will be{' '}
<span className="font-bold text-red-400">lost forever</span>.
</div>
)
return <TransactionFailedOnNetwork networkName={networkName} />
}
if (isDestinationChainFailure) {
return `Transaction failed on ${networkName}.`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import {
} from '../../util/RetryableUtils'
import { TransactionsTableRowAction } from './TransactionsTableRowAction'
import { ExternalLink } from '../common/ExternalLink'
import { Step } from './TransactionsTableDetailsSteps'
import {
Step,
TransactionFailedOnNetwork
} from './TransactionsTableDetailsSteps'
import { DepositCountdown } from '../common/DepositCountdown'

const TeleportMiddleStepFailureExplanationNote = ({
Expand Down Expand Up @@ -78,7 +81,7 @@ export const TransactionsTableDetailsTeleporterSteps = ({
typeof tx.l2ToL3MsgData?.l2ForwarderRetryableTxID === 'undefined'
const l2ChainId = tx.l2ToL3MsgData?.l2ChainId
const isFirstRetryableLegFailed = firstRetryableLegRequiresRedeem(tx)
const _l2ForwarderRequiresRedeem = l2ForwarderRetryableRequiresRedeem(tx)
const l2ForwarderRequiresRedeem = l2ForwarderRetryableRequiresRedeem(tx)

const isFirstRetryableLegResolved =
isFirstRetryableLegSucceeded || isFirstRetryableLegFailed
Expand All @@ -87,31 +90,6 @@ export const TransactionsTableDetailsTeleporterSteps = ({
secondRetryableLegForTeleportRequiresRedeem(tx) ||
typeof tx.l2ToL3MsgData?.l3TxID !== 'undefined'

const firstTransactionText = useMemo(() => {
if (isFirstRetryableLegFailed) {
const l2NetworkName = getNetworkName(getChainIdForRedeemingRetryable(tx))

return (
<div>
Transaction failed on {l2NetworkName}. You have 7 days to try again.
After that, your funds will be{' '}
<span className="font-bold text-red-400">lost forever</span>.
{/* if we detect we will have 2 redemptions in the first leg of teleport, explain it to users */}
{_l2ForwarderRequiresRedeem && (
<TeleportMiddleStepFailureExplanationNote tx={tx} />
)}
</div>
)
}

if (l2ChainId) {
return `Funds arrived on ${getNetworkName(l2ChainId)}`
}

// till the time we don't have information for l2ChainId
return `Funds arrived on intermediate chain`
}, [tx, isFirstRetryableLegFailed, l2ChainId, _l2ForwarderRequiresRedeem])

const firstRetryableRedeemButton = useMemo(
() => (
<TransactionsTableRowAction
Expand Down Expand Up @@ -166,9 +144,16 @@ export const TransactionsTableDetailsTeleporterSteps = ({
<Step
done={isFirstRetryableLegSucceeded}
failure={isFirstRetryableLegFailed}
text={firstTransactionText}
text={
<FirstRetryableLegLabel
tx={tx}
isFirstRetryableLegFailed={isFirstRetryableLegFailed}
l2ForwarderRequiresRedeem={l2ForwarderRequiresRedeem}
l2ChainId={l2ChainId}
/>
}
endItem={firstTransactionActionItem}
extendHeight={_l2ForwarderRequiresRedeem} // when we show the explanatory note, we need more height for this step
extendHeight={l2ForwarderRequiresRedeem} // when we show the explanatory note, we need more height for this step
/>

{/* Show second leg of teleport transfer waiting time */}
Expand All @@ -180,3 +165,37 @@ export const TransactionsTableDetailsTeleporterSteps = ({
</>
)
}

const FirstRetryableLegLabel = ({
tx,
isFirstRetryableLegFailed,
l2ForwarderRequiresRedeem,
l2ChainId
}: {
tx: MergedTransaction
isFirstRetryableLegFailed: boolean
l2ForwarderRequiresRedeem: boolean
l2ChainId?: number
}) => {
if (isFirstRetryableLegFailed) {
const l2NetworkName = getNetworkName(getChainIdForRedeemingRetryable(tx))

return (
<div>
<TransactionFailedOnNetwork networkName={l2NetworkName} />

{/* if we detect we will have 2 redemptions in the first leg of teleport, explain it to users */}
{l2ForwarderRequiresRedeem && (
<TeleportMiddleStepFailureExplanationNote tx={tx} />
)}
</div>
)
}

if (l2ChainId) {
return `Funds arrived on ${getNetworkName(l2ChainId)}`
}

// till the time we don't have information for l2ChainId
return `Funds arrived on intermediate chain`
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { WithdrawalCountdown } from '../common/WithdrawalCountdown'
import { DepositCountdown } from '../common/DepositCountdown'
import { Address } from '../../util/AddressUtils'
import { getChainIdForRedeemingRetryable } from '../../util/RetryableUtils'
import { isTeleport } from '../../token-bridge-sdk/teleport'
import { isTeleport } from '@/token-bridge-sdk/teleport'
import { useRedeemTeleporter } from '../../hooks/useRedeemTeleporter'

export function TransactionsTableRowAction({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { AssetType } from '../../hooks/arbTokenBridge.types'
import { getDepositStatus } from '../../state/app/utils'
import { getBlockBeforeConfirmation } from '../../state/cctpState'
import { getAttestationHashAndMessageFromReceipt } from '../../util/cctp/getAttestationHashAndMessageFromReceipt'
import { isTeleport } from '../../token-bridge-sdk/teleport'
import { isTeleport } from '@/token-bridge-sdk/teleport'

const PARENT_CHAIN_TX_DETAILS_OF_CLAIM_TX =
'arbitrum:bridge:claim:parent:tx:details'
Expand Down Expand Up @@ -462,10 +462,6 @@ export async function getUpdatedCctpTransfer(
export async function getUpdatedTeleportTransfer(
tx: MergedTransaction
): Promise<MergedTransaction> {
if (!isTxPending(tx)) {
return tx
}

const { status, timestampResolved, l1ToL2MsgData, l2ToL3MsgData } =
await fetchTeleporterDepositStatusData(tx)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ export function TokenApprovalDialog(props: TokenApprovalDialogProps) {
parentChainProvider,
token?.address,
sourceChain.id,
destinationChain.id
destinationChain.id,
isTeleportMode
])

function closeWithReset(confirmed: boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function getMinutesRemainingText(minutesRemaining: number): string {

function getEstimatedDepositDurationInMinutes(
tx: MergedTransaction,
firstTxOnly?: boolean
firstTxOnly?: boolean // teleport has 2 txns, this flag will give us estimate of only 1st tx, else it will give consolidated duration
) {
const { parentChainId, sourceChainId, destinationChainId } = tx
if (!parentChainId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function useClaimWithdrawal(
const isSuccess = (res as ContractReceipt).status === 1
const txHash = (res as ContractReceipt).transactionHash

updatePendingTransaction({
await updatePendingTransaction({
...tx,
status: isSuccess ? WithdrawalStatus.EXECUTED : WithdrawalStatus.FAILURE,
resolvedAt: isSuccess ? dayjs().valueOf() : null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function useRedeemRetryable(
l2TxReceipt: TransactionReceipt
}

updatePendingTransaction({
await updatePendingTransaction({
...tx,
l1ToL2MsgData: {
l2TxID: redeemReceipt.l2TxReceipt.transactionHash,
Expand Down
34 changes: 12 additions & 22 deletions packages/arb-token-bridge-ui/src/hooks/useRedeemTeleporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { L1ToL2MessageStatus, L1ToL2MessageWriter } from '@arbitrum/sdk'
import { useSigner } from 'wagmi'
import dayjs from 'dayjs'
import { TransactionReceipt } from '@ethersproject/providers'
import { getProviderForChainId } from '@/token-bridge-sdk/utils'
import { isTeleport } from '@/token-bridge-sdk/teleport'
import { DepositStatus, MergedTransaction } from '../state/app/state'
import {
firstRetryableLegRequiresRedeem,
Expand All @@ -20,12 +22,8 @@ import { errorToast } from '../components/common/atoms/Toast'
import { useTransactionHistory } from './useTransactionHistory'
import { Address } from '../util/AddressUtils'
import { L2ToL3MessageData } from './useTransactions'
import { getProviderForChainId } from '../token-bridge-sdk/utils'
import { fetchTeleporterDepositStatusData } from '../util/deposits/helpers'
import { UseRedeemRetryableResult } from './useRedeemRetryable'
import { getUpdatedTeleportTransfer } from '../components/TransactionHistory/helpers'
import { getDepositStatus } from '../state/app/utils'
import { isTeleport } from '../token-bridge-sdk/teleport'

// common handling for redeeming all 3 retryables for teleporter
const redeemRetryable = async (retryable: L1ToL2MessageWriter) => {
Expand Down Expand Up @@ -76,7 +74,7 @@ const redeemTeleporterFirstLeg = async ({
await redeemRetryable(l1l2Retryable)

// update the teleport tx in the UI
teleportTransfer = await getUpdatedTeleporterTxAfterRedemption(tx)
teleportTransfer = await getUpdatedTeleportTransfer(tx)
await txUpdateCallback?.(teleportTransfer)
}

Expand All @@ -95,7 +93,7 @@ const redeemTeleporterFirstLeg = async ({
await redeemRetryable(l2ForwarderRetryable)

// update the teleport tx in the UI
const updatedTeleportTransfer = await getUpdatedTeleporterTxAfterRedemption(
const updatedTeleportTransfer = await getUpdatedTeleportTransfer(
teleportTransfer
)
await txUpdateCallback?.(updatedTeleportTransfer)
Expand Down Expand Up @@ -145,22 +143,6 @@ const redeemTeleporterSecondLeg = async ({
}
}

const getUpdatedTeleporterTxAfterRedemption = async (tx: MergedTransaction) => {
const { l1ToL2MsgData, l2ToL3MsgData } =
await fetchTeleporterDepositStatusData(tx)

const teleportTransfer = {
...tx,
l1ToL2MsgData,
l2ToL3MsgData
}

return {
...teleportTransfer,
depositStatus: getDepositStatus(teleportTransfer)
}
}

export function useRedeemTeleporter(
tx: MergedTransaction,
address: Address | undefined
Expand Down Expand Up @@ -194,6 +176,14 @@ export function useRedeemTeleporter(
throw 'Signer is undefined'
}

if (
!firstRetryableLegRequiresRedeem(tx) &&
!secondRetryableLegForTeleportRequiresRedeem(tx)
) {
// fail-safe: if there is no retryable to redeem, we should break the flow here
throw 'Transaction does not require redemption.'
}

if (firstRetryableLegRequiresRedeem(tx)) {
await redeemTeleporterFirstLeg({
tx,
Expand Down
16 changes: 12 additions & 4 deletions packages/arb-token-bridge-ui/src/state/app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,23 @@ export const getDepositStatus = (tx: Transaction | MergedTransaction) => {
// if we find `l2ForwarderRetryableTxID` then this tx will need to be redeemed
if (l2ToL3MsgData.l2ForwarderRetryableTxID) return DepositStatus.L2_FAILURE

const depositStatus = getDepositStatusFromL1ToL2MessageStatus(
// if we find first retryable leg failing, then no need to check for the second leg
const firstLegDepositStatus = getDepositStatusFromL1ToL2MessageStatus(
l1ToL2MsgData.status
)
if (firstLegDepositStatus !== DepositStatus.L2_SUCCESS) {
return firstLegDepositStatus
}

const secondLegDepositStatus = getDepositStatusFromL1ToL2MessageStatus(
l2ToL3MsgData.status
)
if (typeof depositStatus !== 'undefined') {
return depositStatus
if (typeof secondLegDepositStatus !== 'undefined') {
return secondLegDepositStatus
}
switch (l1ToL2MsgData.status) {
case L1ToL2MessageStatus.REDEEMED:
return DepositStatus.L2_PENDING // tx is still pending if l1ToL2MsgData is redeemed (but l2ToL3MsgData is not)
return DepositStatus.L2_PENDING // tx is still pending if `l1ToL2MsgData` is redeemed (but l2ToL3MsgData is not)
default:
return getDepositStatusFromL1ToL2MessageStatus(l1ToL2MsgData.status)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/arb-token-bridge-ui/src/state/cctpState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ export function useClaimCctp(tx: MergedTransaction) {
receiveReceiptTx.status === 1
? getStandardizedTimestamp(BigNumber.from(Date.now()).toString())
: null
updatePendingTransaction({
await updatePendingTransaction({
...tx,
resolvedAt,
depositStatus: tx.isWithdrawal ? undefined : DepositStatus.L2_SUCCESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ export class EthTeleportStarter extends BridgeTransferStarter {

const l1l3Bridger = await this.getBridger()

const depositRequest = await l1l3Bridger.getDepositRequest({
l1Signer: signer,
amount,
l1Provider: this.sourceChainProvider,
l2Provider,
l3Provider: this.destinationChainProvider
})

try {
const depositRequest = await l1l3Bridger.getDepositRequest({
l1Signer: signer,
amount,
l1Provider: this.sourceChainProvider,
l2Provider,
l3Provider: this.destinationChainProvider
})

const estimatedParentChainGas =
await this.sourceChainProvider.estimateGas(depositRequest.txRequest)
return {
Expand Down
5 changes: 5 additions & 0 deletions packages/arb-token-bridge-ui/src/util/L2ApprovalUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const L2ApproveTokens: { [chainId: number]: RequireL2ApproveToken[] } = {
symbol: 'ARB',
l1Address: '0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1',
l2Address: '0x912CE59144191C1204E64559FE8253a0e49E6548'
},
{
symbol: 'saETH',
l1Address: '0xF1617882A71467534D14EEe865922de1395c9E89',
l2Address: '0xF1617882A71467534D14EEe865922de1395c9E89'
}
],
[ChainId.ArbitrumNova]: [
Expand Down
2 changes: 1 addition & 1 deletion packages/arb-token-bridge-ui/src/util/RetryableUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { Signer } from '@ethersproject/abstract-signer'
import { Provider } from '@ethersproject/abstract-provider'
import dayjs from 'dayjs'
import { JsonRpcProvider } from '@ethersproject/providers'
import { isTeleport } from '@/token-bridge-sdk/teleport'
import { MergedTransaction } from '../state/app/state'
import { isTeleport } from '../token-bridge-sdk/teleport'

type GetRetryableTicketParams = {
parentChainTxHash: string
Expand Down
Loading

0 comments on commit 75d66c1

Please sign in to comment.