From b0293fc1e6c2e65a07bb8d88599fa61b35037a7c Mon Sep 17 00:00:00 2001 From: Victor Creed Date: Wed, 18 Feb 2026 10:56:09 +0200 Subject: [PATCH] fix: rusdt migration --- .../RusdtMigrationNotice.tsx | 161 ++++++++++++++++++ .../PoolsTable/PoolsTable.constants.tsx | 17 +- .../PoolsTableAction/PoolsTableAction.tsx | 110 ++++++------ .../AssetBalanceRow/AssetBalanceRow.tsx | 36 +++- apps/frontend/src/constants/tokens.ts | 7 + .../frontend/src/locales/en/translations.json | 18 +- 6 files changed, 286 insertions(+), 63 deletions(-) create mode 100644 apps/frontend/src/app/2_molecules/RusdtMigrationNotice/RusdtMigrationNotice.tsx diff --git a/apps/frontend/src/app/2_molecules/RusdtMigrationNotice/RusdtMigrationNotice.tsx b/apps/frontend/src/app/2_molecules/RusdtMigrationNotice/RusdtMigrationNotice.tsx new file mode 100644 index 000000000..f7bdac32c --- /dev/null +++ b/apps/frontend/src/app/2_molecules/RusdtMigrationNotice/RusdtMigrationNotice.tsx @@ -0,0 +1,161 @@ +import React, { FC, useCallback, useMemo, useState } from 'react'; + +import classNames from 'classnames'; +import { t } from 'i18next'; + +import { getAssetData } from '@sovryn/contracts'; +import { + Button, + ButtonSize, + ButtonStyle, + Dialog, + DialogBody, + DialogHeader, + Paragraph, + ParagraphSize, +} from '@sovryn/ui'; +import { Decimal } from '@sovryn/utils'; + +import { RSK_CHAIN_ID } from '../../../config/chains'; + +import { + TransactionType, + Transaction, +} from '../../3_organisms/TransactionStepDialog/TransactionStepDialog.types'; +import { useTransactionContext } from '../../../contexts/TransactionContext'; +import { useAccount } from '../../../hooks/useAccount'; +import { useAssetBalance } from '../../../hooks/useAssetBalance'; +import { translations } from '../../../locales/i18n'; +import { COMMON_SYMBOLS } from '../../../utils/asset'; +import { bigNumberic, decimalic } from '../../../utils/math'; +import { AmountRenderer } from '../AmountRenderer/AmountRenderer'; + +const RUSDT_MIGRATION_CONTRACT = '0xd143f576b8e889b1c90ebef8d0c4bfbb3316fdd2'; + +type RusdtMigrationNoticeProps = { + className?: string; + buttonClassName?: string; + dataAttributePrefix?: string; +}; + +export const RusdtMigrationNotice: FC = ({ + className, + buttonClassName, + dataAttributePrefix = 'rusdt-migration', +}) => { + const { account, signer } = useAccount(); + const { balance, weiBalance, loading } = useAssetBalance( + COMMON_SYMBOLS.RUSDT, + RSK_CHAIN_ID, + ); + + // Convert rUSDT balance to the correct decimals for the migration + const outputWeiBalance = useMemo( + () => bigNumberic(weiBalance).div(1e12).toString(), + [weiBalance], + ); + + const { setTransactions, setTitle, setIsOpen } = useTransactionContext(); + + const [isModalOpen, setIsModalOpen] = useState(false); + + const hasBalance = useMemo(() => balance.gt(Decimal.ZERO), [balance]); + + const canMigrate = + !!account && !!signer && hasBalance && outputWeiBalance !== '0' && !loading; + + const handleOpenModal = useCallback(() => setIsModalOpen(true), []); + const handleCloseModal = useCallback(() => setIsModalOpen(false), []); + + const handleMigrate = useCallback(async () => { + if (!canMigrate || !signer) { + return; + } + + try { + const { contract } = await getAssetData( + COMMON_SYMBOLS.RUSDT, + RSK_CHAIN_ID, + ); + const rusdtContract = contract(signer); + + const transactions: Transaction[] = [ + { + title: t(translations.rusdtMigration.tx.migrate), + request: { + type: TransactionType.signTransaction, + contract: rusdtContract, + fnName: 'transfer', + args: [RUSDT_MIGRATION_CONTRACT, weiBalance], + gasLimit: 100000, // Set a reasonable gas limit for the migration transaction + }, + }, + ]; + + setTransactions(transactions); + setTitle(t(translations.rusdtMigration.tx.title)); + setIsOpen(true); + setIsModalOpen(false); + } catch (error) { + console.error('rUSDT migration setup failed', error); + } + }, [canMigrate, setIsOpen, setTitle, setTransactions, signer, weiBalance]); + + return ( + <> +