From e932176b78f91a2cc47187e4a93597192404e2b9 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Wed, 12 Jul 2023 17:20:34 +0200 Subject: [PATCH 01/22] Rename `getEstimatedFees` function `getEstimatedFees` -> `getEstimatedDepositFees` We are renaming it to avoid any potential confusion, because we can also get estimated fees for redemption. --- .../Modal/TbtcMintingConfirmationModal/index.tsx | 6 +++--- src/hooks/tbtc/useFetchDepositDetails.ts | 2 +- src/hooks/tbtc/useSubsribeToDepositRevealedEvent.ts | 2 +- src/threshold-ts/tbtc/__test__/tbtc.test.ts | 4 ++-- src/threshold-ts/tbtc/index.ts | 10 +++++----- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/Modal/TbtcMintingConfirmationModal/index.tsx b/src/components/Modal/TbtcMintingConfirmationModal/index.tsx index 4bb2cb776..bb62fed2d 100644 --- a/src/components/Modal/TbtcMintingConfirmationModal/index.tsx +++ b/src/components/Modal/TbtcMintingConfirmationModal/index.tsx @@ -73,16 +73,16 @@ const TbtcMintingConfirmationModal: FC = ({ const amount = BigNumber.from(utxo.value).toString() useEffect(() => { - const getEstimatedFees = async () => { + const getEstimatedDepositFees = async () => { const { treasuryFee, optimisticMintFee, amountToMint } = - await threshold.tbtc.getEstimatedFees(amount) + await threshold.tbtc.getEstimatedDepositFees(amount) updateState("mintingFee", optimisticMintFee) updateState("thresholdNetworkFee", treasuryFee) updateState("tBTCMintAmount", amountToMint) } - getEstimatedFees() + getEstimatedDepositFees() }, [amount, updateState, threshold]) return ( diff --git a/src/hooks/tbtc/useFetchDepositDetails.ts b/src/hooks/tbtc/useFetchDepositDetails.ts index bcd7b6418..b476d031b 100644 --- a/src/hooks/tbtc/useFetchDepositDetails.ts +++ b/src/hooks/tbtc/useFetchDepositDetails.ts @@ -74,7 +74,7 @@ export const useFetchDepositDetails = (depositKey: string | undefined) => { threshold.tbtc.minimumNumberOfConfirmationsNeeded(deposit.amount) const { treasuryFee, optimisticMintFee, amountToMint } = - await threshold.tbtc.getEstimatedFees(deposit.amount) + await threshold.tbtc.getEstimatedDepositFees(deposit.amount) setDepositData({ btcTxHash: btcTxHash.toString(), diff --git a/src/hooks/tbtc/useSubsribeToDepositRevealedEvent.ts b/src/hooks/tbtc/useSubsribeToDepositRevealedEvent.ts index 32f592723..e20005523 100644 --- a/src/hooks/tbtc/useSubsribeToDepositRevealedEvent.ts +++ b/src/hooks/tbtc/useSubsribeToDepositRevealedEvent.ts @@ -33,7 +33,7 @@ export const useSubscribeToDepositRevealedEvent = () => { ) => { if (!account || !isSameETHAddress(depositor, account)) return - const { amountToMint } = await threshold.tbtc.getEstimatedFees( + const { amountToMint } = await threshold.tbtc.getEstimatedDepositFees( amount.toString() ) diff --git a/src/threshold-ts/tbtc/__test__/tbtc.test.ts b/src/threshold-ts/tbtc/__test__/tbtc.test.ts index 90b27bf0e..60c064ab2 100644 --- a/src/threshold-ts/tbtc/__test__/tbtc.test.ts +++ b/src/threshold-ts/tbtc/__test__/tbtc.test.ts @@ -447,7 +447,7 @@ describe("TBTC test", () => { }) }) - describe("getEstimatedFees", () => { + describe("getEstimatedDepositFees", () => { const mockDepositTreasuryFeeDivisor = "5000" const mockOptimisticMintingFeeDivisor = "300" const mockAmountToMint = "5000" @@ -478,7 +478,7 @@ describe("TBTC test", () => { amountToMint: mockAmountToMint, optimisticMintFee: mockOptimisticMintFee, }) - estimatedFees = await tBTC.getEstimatedFees(mockDepositAmount) + estimatedFees = await tBTC.getEstimatedDepositFees(mockDepositAmount) }) test("should estimate fees", () => { diff --git a/src/threshold-ts/tbtc/index.ts b/src/threshold-ts/tbtc/index.ts index 0adc1c4ba..7a8f06cb8 100644 --- a/src/threshold-ts/tbtc/index.ts +++ b/src/threshold-ts/tbtc/index.ts @@ -207,11 +207,11 @@ export interface ITBTC { /** * Gets estimated fees that will be payed during a reveal and estimated amount * of tBTC token that will be minted. - * @param depositAmount Amount that will be revealed in Satoshi. - * @returns Treasury fee, optitimistic mint fee and estimated amount of tBTC - * token that will be minted in ERC20 standart. + * @param depositAmount Amount of BTC that will be revealed in Satoshi. + * @returns Treasury fee, optimistic mint fee and estimated amount of tBTC + * token that will be minted in ERC20 standard. */ - getEstimatedFees(depositAmount: string): Promise<{ + getEstimatedDepositFees(depositAmount: string): Promise<{ treasuryFee: string optimisticMintFee: string amountToMint: string @@ -524,7 +524,7 @@ export class TBTC implements ITBTC { return await this._bitcoinClient.findAllUnspentTransactionOutputs(address) } - getEstimatedFees = async (depositAmount: string) => { + getEstimatedDepositFees = async (depositAmount: string) => { const { depositTreasuryFeeDivisor, optimisticMintingFeeDivisor } = await this._getDepositFees() From b0d8c3c5fb6404a03f4d1cd49e1dbd14d1638042 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Wed, 12 Jul 2023 18:17:43 +0200 Subject: [PATCH 02/22] Create `getEstimatedRedemptionFees` function Create `getEstimatedRedemptionFees` function in TBTC class that will get estimated fees that will be payed during a redemption and estimated amount of BTC that will be redeemed. --- src/threshold-ts/tbtc/index.ts | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/threshold-ts/tbtc/index.ts b/src/threshold-ts/tbtc/index.ts index 7a8f06cb8..05456d499 100644 --- a/src/threshold-ts/tbtc/index.ts +++ b/src/threshold-ts/tbtc/index.ts @@ -373,6 +373,18 @@ export interface ITBTC { getRedemptionsCompletedEvents( filter: RedemptionsCompletedEventFilter ): Promise + + /** + * Gets estimated fees that will be payed during a redemption and estimated + * amount of BTC that will be redeemed. + * @param redemptionAmount Amount of tbtc requested for redemption. + * @returns Treasury fee and estimated amount of BTC that will be redeemed (in + * satoshi). + */ + getEstimatedRedemptionFees(redemptionAmount: string): Promise<{ + treasuryFee: string + estimatedAmountToBeReceived: string + }> } export class TBTC implements ITBTC { @@ -1115,4 +1127,27 @@ export class TBTC implements ITBTC { txHash: log.transactionHash, })) } + + getEstimatedRedemptionFees = async ( + redemptionAmount: string + ): Promise<{ + treasuryFee: string + estimatedAmountToBeReceived: string + }> => { + const { redemptionTreasuryFeeDivisor } = + await this.bridgeContract.redemptionParameters() + + const treasuryFee = BigNumber.from(redemptionTreasuryFeeDivisor).gt(0) + ? BigNumber.from(redemptionAmount).div(redemptionTreasuryFeeDivisor) + : ZERO + + const estimatedAmountToBeReceived = BigNumber.from(redemptionAmount) + .sub(treasuryFee) + .mul(this._satoshiMultiplier) + + return { + treasuryFee: treasuryFee.toString(), + estimatedAmountToBeReceived: estimatedAmountToBeReceived.toString(), + } + } } From 5e06caff77551c782ac4bf92ffb8f31fcd5ae4aa Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Wed, 12 Jul 2023 18:43:59 +0200 Subject: [PATCH 03/22] FIx calculation in `getEstimatedRedemptionFees` --- src/threshold-ts/tbtc/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/threshold-ts/tbtc/index.ts b/src/threshold-ts/tbtc/index.ts index 05456d499..7a2fb1acf 100644 --- a/src/threshold-ts/tbtc/index.ts +++ b/src/threshold-ts/tbtc/index.ts @@ -378,8 +378,8 @@ export interface ITBTC { * Gets estimated fees that will be payed during a redemption and estimated * amount of BTC that will be redeemed. * @param redemptionAmount Amount of tbtc requested for redemption. - * @returns Treasury fee and estimated amount of BTC that will be redeemed (in - * satoshi). + * @returns Treasury fee and estimated amount of BTC that will be redeemed + * (both in satoshi). */ getEstimatedRedemptionFees(redemptionAmount: string): Promise<{ treasuryFee: string @@ -1143,7 +1143,7 @@ export class TBTC implements ITBTC { const estimatedAmountToBeReceived = BigNumber.from(redemptionAmount) .sub(treasuryFee) - .mul(this._satoshiMultiplier) + .div(this._satoshiMultiplier) return { treasuryFee: treasuryFee.toString(), From e5d93fe6c374d120ac22a4ccb30d7fe83c9e3792 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Thu, 13 Jul 2023 11:29:41 +0200 Subject: [PATCH 04/22] Display proper values in InitiateUnminting modal Display proper values for btc amount and threshold network fee. --- .../Modal/tBTC/InitiateUnminting.tsx | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index 21ba1c12a..c6a3b4b76 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -10,8 +10,9 @@ import { ModalHeader, } from "@threshold-network/components" import { useWeb3React } from "@web3-react/core" -import { FC } from "react" +import { FC, useEffect, useState } from "react" import { useNavigate } from "react-router-dom" +import { useThreshold } from "../../../contexts/ThresholdContext" import { useRequestRedemption } from "../../../hooks/tbtc" import { BaseModalProps, @@ -47,11 +48,23 @@ const InitiateUnmintingBase: FC = ({ }) => { const navigate = useNavigate() const { account } = useWeb3React() - // TODO: calculate the BTC amount- take into account fees - const btcAmount = unmintAmount - const thresholdNetworkFee = "0" + const threshold = useThreshold() + const [estimatedBTCAmount, setEstimatedBTCAmount] = useState("0") + const [thresholdNetworkFee, setThresholdNetworkFee] = useState("0") const btcMinerFee = "0" + useEffect(() => { + const getEstimatedDepositFees = async () => { + const { treasuryFee, estimatedAmountToBeReceived } = + await threshold.tbtc.getEstimatedRedemptionFees(unmintAmount) + + setThresholdNetworkFee(treasuryFee) + setEstimatedBTCAmount(estimatedAmountToBeReceived) + } + + getEstimatedDepositFees() + }, [unmintAmount, threshold]) + const onSuccess: OnSuccessCallback = (receipt) => { navigate( buildRedemptionDetailsLink( @@ -79,7 +92,14 @@ const InitiateUnmintingBase: FC = ({
Through unminting you will get back{" "} - BTC + {" "} + BTC
Unminting tBTC requires one transaction on your end. From 73359995adc66a175531b132d066a119aa87cce0 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Thu, 13 Jul 2023 11:34:10 +0200 Subject: [PATCH 05/22] Remove bitcoinMinerFee from InitateUnminting --- src/components/Modal/tBTC/InitiateUnminting.tsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index c6a3b4b76..3366a6721 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -51,7 +51,6 @@ const InitiateUnmintingBase: FC = ({ const threshold = useThreshold() const [estimatedBTCAmount, setEstimatedBTCAmount] = useState("0") const [thresholdNetworkFee, setThresholdNetworkFee] = useState("0") - const btcMinerFee = "0" useEffect(() => { const getEstimatedDepositFees = async () => { @@ -113,14 +112,6 @@ const InitiateUnmintingBase: FC = ({ precision={6} higherPrecision={8} /> - Date: Thu, 13 Jul 2023 11:49:32 +0200 Subject: [PATCH 06/22] Always display tilde for btc amount We want to always display tilde for btc amount because we are not able to easily calculate the bitcoin miner fee and thus we are not able to subtract it from the btc amount. --- src/components/Modal/tBTC/InitiateUnminting.tsx | 3 ++- src/components/TokenBalance.tsx | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index 3366a6721..997d96ebf 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -90,13 +90,14 @@ const InitiateUnmintingBase: FC = ({
- Through unminting you will get back{" "} + Through unminting you will get back{" ~"} {" "} BTC
diff --git a/src/components/TokenBalance.tsx b/src/components/TokenBalance.tsx index 43e2ddfda..bf5d41b93 100644 --- a/src/components/TokenBalance.tsx +++ b/src/components/TokenBalance.tsx @@ -30,6 +30,7 @@ export interface TokenBalanceProps { withHigherPrecision?: boolean precision?: number higherPrecision?: number + displayTildeBelow?: number } export const InlineTokenBalance: FC = ({ @@ -41,6 +42,7 @@ export const InlineTokenBalance: FC = ({ precision = 2, higherPrecision = 6, withHigherPrecision, + displayTildeBelow = 1, ...restProps }) => { const _tokenAmount = useMemo(() => { @@ -48,7 +50,8 @@ export const InlineTokenBalance: FC = ({ tokenAmount || 0, tokenFormat, tokenDecimals, - precision + precision, + displayTildeBelow ) }, [tokenAmount, tokenFormat, tokenDecimals, precision]) From 4512cc85341afe261d5ac3ae518a6a6d0695721b Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Thu, 13 Jul 2023 12:42:35 +0200 Subject: [PATCH 07/22] Improve calculation of redemption fees Add note in comment that `redemptionAmount` should be in ERC20 standard (16 decimals). For calculating the fees we will operate on satoshis and return both `treasuryFee` and `estimatedAmountToBeReceived` in satoshis. --- src/components/Modal/tBTC/InitiateUnminting.tsx | 5 +++-- src/threshold-ts/tbtc/index.ts | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index 997d96ebf..2a18e2a90 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -115,10 +115,11 @@ const InitiateUnmintingBase: FC = ({ /> => { + const { satoshis: redemptionAmountInSatoshi } = + this._amountToSatoshi(redemptionAmount) + const { redemptionTreasuryFeeDivisor } = await this.bridgeContract.redemptionParameters() + // https://github.com/keep-network/tbtc-v2/blob/main/solidity/contracts/bridge/Redemption.sol#L478 const treasuryFee = BigNumber.from(redemptionTreasuryFeeDivisor).gt(0) - ? BigNumber.from(redemptionAmount).div(redemptionTreasuryFeeDivisor) + ? BigNumber.from(redemptionAmountInSatoshi).div( + redemptionTreasuryFeeDivisor + ) : ZERO - const estimatedAmountToBeReceived = BigNumber.from(redemptionAmount) - .sub(treasuryFee) - .div(this._satoshiMultiplier) + const estimatedAmountToBeReceived = BigNumber.from( + redemptionAmountInSatoshi + ).sub(treasuryFee) return { treasuryFee: treasuryFee.toString(), From c729940f799ee82b3d0de39d9ecdfeca1cd9bc33 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Thu, 13 Jul 2023 12:48:30 +0200 Subject: [PATCH 08/22] Create `useRedemptionEstimatedFees` hook Creates `useRedemptionEstimatedFees` hook where we can get the estimated BTC amount that we will receive from a redemption and threshold network fee that we will pay during a redemption. --- .../Modal/tBTC/InitiateUnminting.tsx | 25 ++++++------------- src/hooks/tbtc/index.ts | 13 +++++----- src/hooks/tbtc/useRedemptionEstimatedFees.ts | 22 ++++++++++++++++ 3 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 src/hooks/tbtc/useRedemptionEstimatedFees.ts diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index 2a18e2a90..694ef6c24 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -10,10 +10,12 @@ import { ModalHeader, } from "@threshold-network/components" import { useWeb3React } from "@web3-react/core" -import { FC, useEffect, useState } from "react" +import { FC } from "react" import { useNavigate } from "react-router-dom" -import { useThreshold } from "../../../contexts/ThresholdContext" -import { useRequestRedemption } from "../../../hooks/tbtc" +import { + useRedemptionEstimatedFees, + useRequestRedemption, +} from "../../../hooks/tbtc" import { BaseModalProps, UnspentTransactionOutputPlainObject, @@ -48,21 +50,8 @@ const InitiateUnmintingBase: FC = ({ }) => { const navigate = useNavigate() const { account } = useWeb3React() - const threshold = useThreshold() - const [estimatedBTCAmount, setEstimatedBTCAmount] = useState("0") - const [thresholdNetworkFee, setThresholdNetworkFee] = useState("0") - - useEffect(() => { - const getEstimatedDepositFees = async () => { - const { treasuryFee, estimatedAmountToBeReceived } = - await threshold.tbtc.getEstimatedRedemptionFees(unmintAmount) - - setThresholdNetworkFee(treasuryFee) - setEstimatedBTCAmount(estimatedAmountToBeReceived) - } - - getEstimatedDepositFees() - }, [unmintAmount, threshold]) + const { estimatedBTCAmount, thresholdNetworkFee } = + useRedemptionEstimatedFees(unmintAmount) const onSuccess: OnSuccessCallback = (receipt) => { navigate( diff --git a/src/hooks/tbtc/index.ts b/src/hooks/tbtc/index.ts index 5f25dd9f9..0e05674a9 100644 --- a/src/hooks/tbtc/index.ts +++ b/src/hooks/tbtc/index.ts @@ -1,10 +1,11 @@ -export * from "./useRevealDepositTransaction" -export * from "./useTBTCDepositDataFromLocalStorage" -export * from "./useTBTCVaultContract" -export * from "./useSubscribeToOptimisticMintingFinalizedEvent" -export * from "./useSubsribeToDepositRevealedEvent" -export * from "./useSubscribeToOptimisticMintingRequestedEvent" export * from "./useFetchDepositDetails" export * from "./useFetchRecentDeposits" export * from "./useFetchTBTCMetrics" +export * from "./useRedemptionEstimatedFees" export * from "./useRequestRedemption" +export * from "./useRevealDepositTransaction" +export * from "./useSubscribeToOptimisticMintingFinalizedEvent" +export * from "./useSubscribeToOptimisticMintingRequestedEvent" +export * from "./useSubsribeToDepositRevealedEvent" +export * from "./useTBTCDepositDataFromLocalStorage" +export * from "./useTBTCVaultContract" diff --git a/src/hooks/tbtc/useRedemptionEstimatedFees.ts b/src/hooks/tbtc/useRedemptionEstimatedFees.ts new file mode 100644 index 000000000..261193845 --- /dev/null +++ b/src/hooks/tbtc/useRedemptionEstimatedFees.ts @@ -0,0 +1,22 @@ +import { useEffect, useState } from "react" +import { useThreshold } from "../../contexts/ThresholdContext" + +export const useRedemptionEstimatedFees = (unmintedAmount: string) => { + const threshold = useThreshold() + const [estimatedBTCAmount, setEstimatedBTCAmount] = useState("0") + const [thresholdNetworkFee, setThresholdNetworkFee] = useState("0") + + useEffect(() => { + const getEstimatedRedemptionFees = async () => { + const { treasuryFee, estimatedAmountToBeReceived } = + await threshold.tbtc.getEstimatedRedemptionFees(unmintedAmount) + + setThresholdNetworkFee(treasuryFee) + setEstimatedBTCAmount(estimatedAmountToBeReceived) + } + + getEstimatedRedemptionFees() + }, [unmintedAmount, threshold]) + + return { estimatedBTCAmount, thresholdNetworkFee } +} From 0aad8903153e21e9a563364b60dce2fd8af6b202 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Thu, 13 Jul 2023 13:18:38 +0200 Subject: [PATCH 09/22] Display BTC and fees in UnmintDetails Display estimated BTC that will be received and fees in UnmintDetails. Besides that I've added `isEstimated` parameter to `formatTokenAmount` function - it displays the tilde next to the amount no matter the value. --- .../Modal/tBTC/InitiateUnminting.tsx | 3 +- src/components/TokenBalance.tsx | 9 +++-- src/hooks/tbtc/useFetchRedemptionDetails.ts | 3 ++ src/pages/tBTC/Bridge/UnmintDetails.tsx | 35 +++++++++++++------ src/utils/formatAmount.ts | 8 +++-- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index 694ef6c24..7148ac202 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -79,7 +79,7 @@ const InitiateUnmintingBase: FC = ({
- Through unminting you will get back{" ~"} + Through unminting you will get back{" "} = ({ higherPrecision={8} tokenAmount={estimatedBTCAmount} displayTildeBelow={0} + isEstimated />{" "} BTC
diff --git a/src/components/TokenBalance.tsx b/src/components/TokenBalance.tsx index bf5d41b93..3e4f720a7 100644 --- a/src/components/TokenBalance.tsx +++ b/src/components/TokenBalance.tsx @@ -31,6 +31,7 @@ export interface TokenBalanceProps { precision?: number higherPrecision?: number displayTildeBelow?: number + isEstimated?: boolean } export const InlineTokenBalance: FC = ({ @@ -43,6 +44,7 @@ export const InlineTokenBalance: FC = ({ higherPrecision = 6, withHigherPrecision, displayTildeBelow = 1, + isEstimated = false, ...restProps }) => { const _tokenAmount = useMemo(() => { @@ -51,7 +53,8 @@ export const InlineTokenBalance: FC = ({ tokenFormat, tokenDecimals, precision, - displayTildeBelow + displayTildeBelow, + isEstimated ) }, [tokenAmount, tokenFormat, tokenDecimals, precision]) @@ -60,7 +63,9 @@ export const InlineTokenBalance: FC = ({ tokenAmount || 0, tokenFormat, tokenDecimals, - higherPrecision + higherPrecision, + 1, + isEstimated ) }, [tokenAmount, tokenFormat, tokenDecimals, higherPrecision]) diff --git a/src/hooks/tbtc/useFetchRedemptionDetails.ts b/src/hooks/tbtc/useFetchRedemptionDetails.ts index cc1d49ddd..2a3b352e9 100644 --- a/src/hooks/tbtc/useFetchRedemptionDetails.ts +++ b/src/hooks/tbtc/useFetchRedemptionDetails.ts @@ -14,6 +14,7 @@ interface RedemptionDetails { } requestedAt: number completedAt?: number + treasuryFee: string isTimedOut: boolean redemptionTimedOutTxHash?: string btcAddress?: string @@ -158,6 +159,7 @@ export const useFetchRedemptionDetails = ( redemptionCompletedTxHash: undefined, requestedAt: requestedAt, redemptionTimedOutTxHash: timedOutTxHash, + treasuryFee: redemptionRequest.treasuryFee, isTimedOut, }) return @@ -205,6 +207,7 @@ export const useFetchRedemptionDetails = ( }, requestedAt: redemptionRequestedEventTimestamp, completedAt: redemptionCompletedTimestamp, + treasuryFee: redemptionRequest.treasuryFee, isTimedOut: false, // TODO: convert the `scriptPubKey` to address. btcAddress: "2Mzs2YNphdHmBoE7SE77cGB57JBXveNGtae", diff --git a/src/pages/tBTC/Bridge/UnmintDetails.tsx b/src/pages/tBTC/Bridge/UnmintDetails.tsx index a1eab1911..88f76752a 100644 --- a/src/pages/tBTC/Bridge/UnmintDetails.tsx +++ b/src/pages/tBTC/Bridge/UnmintDetails.tsx @@ -52,6 +52,7 @@ import { ProcessCompletedBrandGradientIcon } from "./components/BridgeProcessDet import { featureFlags } from "../../../constants" import { useFetchRedemptionDetails } from "../../../hooks/tbtc/useFetchRedemptionDetails" import { BridgeProcessDetailsPageSkeleton } from "./components/BridgeProcessDetailsPageSkeleton" +import { BigNumber } from "ethers" const pendingRedemption = { redemptionRequestedTxHash: @@ -95,9 +96,15 @@ export const UnmintDetails: PageComponent = () => { }, [btcTxHash]) const isProcessCompleted = !!data?.redemptionCompletedTxHash?.bitcoin - const unmintedAmount = data?.amount ?? "0" + // requested unmint amount of tBTC in satoshi!. This means that this value is + // the amount before subtracting the fees. + const unmintAmount = data?.amount ?? "0" + + const thresholdNetworkFee = data?.treasuryFee ?? "0" + const estimatedAmountToBeReceived = BigNumber.from(unmintAmount) + .sub(thresholdNetworkFee) + .toString() const btcAddress = data?.btcAddress - const fee = "20000000000000000" const time = dateAs( (data?.completedAt ?? dateToUnixTimestamp()) - (data?.requestedAt ?? 0) ) @@ -145,12 +152,15 @@ export const UnmintDetails: PageComponent = () => { )} @@ -214,8 +224,8 @@ export const UnmintDetails: PageComponent = () => { {shouldDisplaySuccessStep || isProcessCompleted ? ( ) : ( @@ -290,10 +300,10 @@ export const UnmintDetails: PageComponent = () => { } const SuccessStep: FC<{ - unmintedAmount: string + estimatedAmountToBeReceived: string thresholdNetworkFee: string btcAddress: string -}> = ({ unmintedAmount, thresholdNetworkFee, btcAddress }) => { +}> = ({ estimatedAmountToBeReceived, thresholdNetworkFee, btcAddress }) => { return ( <>
Success!
@@ -301,16 +311,19 @@ const SuccessStep: FC<{ diff --git a/src/utils/formatAmount.ts b/src/utils/formatAmount.ts index 39ba78ed7..d041f99ec 100644 --- a/src/utils/formatAmount.ts +++ b/src/utils/formatAmount.ts @@ -11,7 +11,8 @@ export const formatTokenAmount = ( format = "0,00.[0]0", decimals = 18, precision = 2, - displayTildeBelow = 1 + displayTildeBelow = 1, + isEstimated = false // adds tilde to the amount no matter the value ) => { const minAmountToDisplay = BigNumber.from(10).pow(decimals - precision) const _rawAmount = BigNumber.from(rawAmount) @@ -39,9 +40,10 @@ export const formatTokenAmount = ( const amountFromFormattedValue = numeral(formattedAmount).value() ?? 0 if ( - Number.parseFloat(amountFromFormattedValue.toString()) !== + isEstimated || + (Number.parseFloat(amountFromFormattedValue.toString()) !== Number.parseFloat(tokenAmountInHumanReadableFormat) && - displayTildeBelow > amountFromFormattedValue + displayTildeBelow > amountFromFormattedValue) ) { return `~${formattedAmount}` } From fc2b7a7f7f3152a7849a5d6167cfbcf786389d8f Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 09:45:10 +0200 Subject: [PATCH 10/22] Rename `redemptionRequest` `redemptionRequest` -> `redemptionRequestedEvent` We assign here result of the `getRedemptionRequestedEvents` + find so it indicates that it's an event. --- src/hooks/tbtc/useFetchRedemptionDetails.ts | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hooks/tbtc/useFetchRedemptionDetails.ts b/src/hooks/tbtc/useFetchRedemptionDetails.ts index 6e1e7d940..fb4547b09 100644 --- a/src/hooks/tbtc/useFetchRedemptionDetails.ts +++ b/src/hooks/tbtc/useFetchRedemptionDetails.ts @@ -75,7 +75,7 @@ export const useFetchRedemptionDetails = ( // the request actually happened. We need `redeemer` address as well to // reduce the number of records - any user can request redemption for // the same wallet. - const redemptionRequest = ( + const redemptionRequestedEvent = ( await threshold.tbtc.getRedemptionRequestedEvents({ walletPublicKeyHash, redeemer, @@ -108,12 +108,12 @@ export const useFetchRedemptionDetails = ( ) === redemptionKey ) - if (!redemptionRequest) { + if (!redemptionRequestedEvent) { throw new Error("Redemption not found...") } const { timestamp: redemptionRequestedEventTimestamp } = await getBlock( - redemptionRequest.blockNumber + redemptionRequestedEvent.blockNumber ) // We need to check if the redemption has `pending` or `timedOut` status. @@ -132,7 +132,7 @@ export const useFetchRedemptionDetails = ( ? ( await threshold.tbtc.getRedemptionTimedOutEvents({ walletPublicKeyHash, - fromBlock: redemptionRequest.blockNumber, + fromBlock: redemptionRequestedEvent.blockNumber, }) ).find( (event) => event.redeemerOutputScript === redeemerOutputScript @@ -157,12 +157,12 @@ export const useFetchRedemptionDetails = ( requestedAt === redemptionRequestedEventTimestamp ) { setRedemptionData({ - amount: redemptionRequest.amount, - redemptionRequestedTxHash: redemptionRequest.txHash, + amount: redemptionRequestedEvent.amount, + redemptionRequestedTxHash: redemptionRequestedEvent.txHash, redemptionCompletedTxHash: undefined, requestedAt: requestedAt, redemptionTimedOutTxHash: timedOutTxHash, - treasuryFee: redemptionRequest.treasuryFee, + treasuryFee: redemptionRequestedEvent.treasuryFee, isTimedOut, }) return @@ -175,7 +175,7 @@ export const useFetchRedemptionDetails = ( const redemptionCompletedEvents = await threshold.tbtc.getRedemptionsCompletedEvents({ walletPublicKeyHash, - fromBlock: redemptionRequest.blockNumber, + fromBlock: redemptionRequestedEvent.blockNumber, }) // For each event we should take `redemptionTxHash` param from @@ -194,7 +194,7 @@ export const useFetchRedemptionDetails = ( for (const { scriptPubKey } of outputs) { if ( prependScriptPubKeyByLength(scriptPubKey.toString()) !== - redemptionRequest.redeemerOutputScript + redemptionRequestedEvent.redeemerOutputScript ) continue @@ -202,15 +202,15 @@ export const useFetchRedemptionDetails = ( redemptionCompletedBlockNumber ) setRedemptionData({ - amount: redemptionRequest.amount, - redemptionRequestedTxHash: redemptionRequest.txHash, + amount: redemptionRequestedEvent.amount, + redemptionRequestedTxHash: redemptionRequestedEvent.txHash, redemptionCompletedTxHash: { chain: txHash, bitcoin: redemptionBitcoinTxHash, }, requestedAt: redemptionRequestedEventTimestamp, completedAt: redemptionCompletedTimestamp, - treasuryFee: redemptionRequest.treasuryFee, + treasuryFee: redemptionRequestedEvent.treasuryFee, isTimedOut: false, btcAddress: createAddressFromOutputScript( scriptPubKey, From 904fa824c41e989df722b052506ecba00d942e62 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 12:48:00 +0200 Subject: [PATCH 11/22] Add requested [tBTC] and received [BTC] amount Add requested and received amounts to the success and in progress page of redemption. --- src/hooks/tbtc/useFetchRedemptionDetails.ts | 13 ++++++--- src/pages/tBTC/Bridge/UnmintDetails.tsx | 29 ++++++++++++--------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/hooks/tbtc/useFetchRedemptionDetails.ts b/src/hooks/tbtc/useFetchRedemptionDetails.ts index fb4547b09..4cba6f437 100644 --- a/src/hooks/tbtc/useFetchRedemptionDetails.ts +++ b/src/hooks/tbtc/useFetchRedemptionDetails.ts @@ -1,3 +1,4 @@ +import { BigNumber } from "ethers" import { useEffect, useState } from "react" import { useThreshold } from "../../contexts/ThresholdContext" import { @@ -9,7 +10,8 @@ import { useGetBlock } from "../../web3/hooks" import { isEmptyOrZeroAddress } from "../../web3/utils" interface RedemptionDetails { - amount: string + requestedAmount: string + receivedAmount?: string redemptionRequestedTxHash: string redemptionCompletedTxHash?: { chain: string @@ -157,7 +159,7 @@ export const useFetchRedemptionDetails = ( requestedAt === redemptionRequestedEventTimestamp ) { setRedemptionData({ - amount: redemptionRequestedEvent.amount, + requestedAmount: redemptionRequestedEvent.amount, redemptionRequestedTxHash: redemptionRequestedEvent.txHash, redemptionCompletedTxHash: undefined, requestedAt: requestedAt, @@ -191,7 +193,7 @@ export const useFetchRedemptionDetails = ( redemptionBitcoinTxHash ) - for (const { scriptPubKey } of outputs) { + for (const { scriptPubKey, value } of outputs) { if ( prependScriptPubKeyByLength(scriptPubKey.toString()) !== redemptionRequestedEvent.redeemerOutputScript @@ -202,7 +204,10 @@ export const useFetchRedemptionDetails = ( redemptionCompletedBlockNumber ) setRedemptionData({ - amount: redemptionRequestedEvent.amount, + requestedAmount: BigNumber.from(redemptionRequestedEvent.amount) + .mul(BigNumber.from(10).pow(10)) + .toString(), + receivedAmount: value.toString(), redemptionRequestedTxHash: redemptionRequestedEvent.txHash, redemptionCompletedTxHash: { chain: txHash, diff --git a/src/pages/tBTC/Bridge/UnmintDetails.tsx b/src/pages/tBTC/Bridge/UnmintDetails.tsx index 88f76752a..cfbbbd142 100644 --- a/src/pages/tBTC/Bridge/UnmintDetails.tsx +++ b/src/pages/tBTC/Bridge/UnmintDetails.tsx @@ -98,12 +98,10 @@ export const UnmintDetails: PageComponent = () => { const isProcessCompleted = !!data?.redemptionCompletedTxHash?.bitcoin // requested unmint amount of tBTC in satoshi!. This means that this value is // the amount before subtracting the fees. - const unmintAmount = data?.amount ?? "0" + const requestedAmount = data?.requestedAmount ?? "0" + const receivedAmount = data?.receivedAmount ?? "0" const thresholdNetworkFee = data?.treasuryFee ?? "0" - const estimatedAmountToBeReceived = BigNumber.from(unmintAmount) - .sub(thresholdNetworkFee) - .toString() const btcAddress = data?.btcAddress const time = dateAs( (data?.completedAt ?? dateToUnixTimestamp()) - (data?.requestedAt ?? 0) @@ -152,15 +150,12 @@ export const UnmintDetails: PageComponent = () => { )} @@ -224,7 +219,8 @@ export const UnmintDetails: PageComponent = () => { {shouldDisplaySuccessStep || isProcessCompleted ? ( @@ -300,10 +296,11 @@ export const UnmintDetails: PageComponent = () => { } const SuccessStep: FC<{ - estimatedAmountToBeReceived: string + requestedAmount: string + receivedAmount: string thresholdNetworkFee: string btcAddress: string -}> = ({ estimatedAmountToBeReceived, thresholdNetworkFee, btcAddress }) => { +}> = ({ requestedAmount, receivedAmount, thresholdNetworkFee, btcAddress }) => { return ( <>
Success!
@@ -311,13 +308,19 @@ const SuccessStep: FC<{ + Date: Fri, 14 Jul 2023 12:59:29 +0200 Subject: [PATCH 12/22] Add skeletons in InitiateUnminting modal --- .../Modal/tBTC/InitiateUnminting.tsx | 21 +++++++++++-------- src/hooks/tbtc/useRedemptionEstimatedFees.ts | 8 +++++-- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index 7148ac202..609d455bf 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -8,6 +8,7 @@ import { ModalBody, ModalFooter, ModalHeader, + Skeleton, } from "@threshold-network/components" import { useWeb3React } from "@web3-react/core" import { FC } from "react" @@ -80,15 +81,17 @@ const InitiateUnmintingBase: FC = ({
Through unminting you will get back{" "} - {" "} + + {" "} + BTC
diff --git a/src/hooks/tbtc/useRedemptionEstimatedFees.ts b/src/hooks/tbtc/useRedemptionEstimatedFees.ts index 261193845..13b4895a3 100644 --- a/src/hooks/tbtc/useRedemptionEstimatedFees.ts +++ b/src/hooks/tbtc/useRedemptionEstimatedFees.ts @@ -3,8 +3,12 @@ import { useThreshold } from "../../contexts/ThresholdContext" export const useRedemptionEstimatedFees = (unmintedAmount: string) => { const threshold = useThreshold() - const [estimatedBTCAmount, setEstimatedBTCAmount] = useState("0") - const [thresholdNetworkFee, setThresholdNetworkFee] = useState("0") + const [estimatedBTCAmount, setEstimatedBTCAmount] = useState< + string | undefined + >(undefined) + const [thresholdNetworkFee, setThresholdNetworkFee] = useState< + string | undefined + >(undefined) useEffect(() => { const getEstimatedRedemptionFees = async () => { From 2a479ff5db280461a06d44493ddd27f3a00ec42d Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 13:04:35 +0200 Subject: [PATCH 13/22] Remove `isEstimated` from `formatTokenAmount` We don't need that parameter in `formatTokenAmount` and we can just keep it in `InlineTokenBalance`. --- src/components/TokenBalance.tsx | 13 +++++++------ src/utils/formatAmount.ts | 8 +++----- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/components/TokenBalance.tsx b/src/components/TokenBalance.tsx index 3e4f720a7..ee1cfd5a9 100644 --- a/src/components/TokenBalance.tsx +++ b/src/components/TokenBalance.tsx @@ -53,8 +53,7 @@ export const InlineTokenBalance: FC = ({ tokenFormat, tokenDecimals, precision, - displayTildeBelow, - isEstimated + displayTildeBelow ) }, [tokenAmount, tokenFormat, tokenDecimals, precision]) @@ -64,14 +63,16 @@ export const InlineTokenBalance: FC = ({ tokenFormat, tokenDecimals, higherPrecision, - 1, - isEstimated + 1 ) }, [tokenAmount, tokenFormat, tokenDecimals, higherPrecision]) return ( - - {`${_tokenAmount}${ + + {`${isEstimated ? "`" : ""}${_tokenAmount}${ withSymbol ? ` ${tokenSymbol}` : "" }`} diff --git a/src/utils/formatAmount.ts b/src/utils/formatAmount.ts index d041f99ec..39ba78ed7 100644 --- a/src/utils/formatAmount.ts +++ b/src/utils/formatAmount.ts @@ -11,8 +11,7 @@ export const formatTokenAmount = ( format = "0,00.[0]0", decimals = 18, precision = 2, - displayTildeBelow = 1, - isEstimated = false // adds tilde to the amount no matter the value + displayTildeBelow = 1 ) => { const minAmountToDisplay = BigNumber.from(10).pow(decimals - precision) const _rawAmount = BigNumber.from(rawAmount) @@ -40,10 +39,9 @@ export const formatTokenAmount = ( const amountFromFormattedValue = numeral(formattedAmount).value() ?? 0 if ( - isEstimated || - (Number.parseFloat(amountFromFormattedValue.toString()) !== + Number.parseFloat(amountFromFormattedValue.toString()) !== Number.parseFloat(tokenAmountInHumanReadableFormat) && - displayTildeBelow > amountFromFormattedValue) + displayTildeBelow > amountFromFormattedValue ) { return `~${formattedAmount}` } From cb200bfd9445f6f59658416f6cde78e8aa126764 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 13:10:45 +0200 Subject: [PATCH 14/22] Add TODO --- src/hooks/tbtc/useFetchRedemptionDetails.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hooks/tbtc/useFetchRedemptionDetails.ts b/src/hooks/tbtc/useFetchRedemptionDetails.ts index 4cba6f437..25c989fad 100644 --- a/src/hooks/tbtc/useFetchRedemptionDetails.ts +++ b/src/hooks/tbtc/useFetchRedemptionDetails.ts @@ -204,6 +204,8 @@ export const useFetchRedemptionDetails = ( redemptionCompletedBlockNumber ) setRedemptionData({ + // TODO: Use satoshi <-> IERC20 conversion function from + // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 requestedAmount: BigNumber.from(redemptionRequestedEvent.amount) .mul(BigNumber.from(10).pow(10)) .toString(), From 7817fcabfdc039bcc2ffa613ce19dedb1385139e Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 14:28:55 +0200 Subject: [PATCH 15/22] Fix double tilde bug in some cases We need to force `displayTildeBelo` to be 0 when `isEstimated` is set to true. --- src/components/TokenBalance.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/TokenBalance.tsx b/src/components/TokenBalance.tsx index ee1cfd5a9..42692c211 100644 --- a/src/components/TokenBalance.tsx +++ b/src/components/TokenBalance.tsx @@ -53,7 +53,7 @@ export const InlineTokenBalance: FC = ({ tokenFormat, tokenDecimals, precision, - displayTildeBelow + isEstimated ? 0 : displayTildeBelow ) }, [tokenAmount, tokenFormat, tokenDecimals, precision]) @@ -63,7 +63,7 @@ export const InlineTokenBalance: FC = ({ tokenFormat, tokenDecimals, higherPrecision, - 1 + isEstimated ? 0 : 1 ) }, [tokenAmount, tokenFormat, tokenDecimals, higherPrecision]) @@ -72,7 +72,7 @@ export const InlineTokenBalance: FC = ({ label={`${isEstimated ? "~" : ""}${_tokenAmountWithHigherPrecision}`} placement="top" > - {`${isEstimated ? "`" : ""}${_tokenAmount}${ + {`${isEstimated ? "~" : ""}${_tokenAmount}${ withSymbol ? ` ${tokenSymbol}` : "" }`} From 2c5be5433d26910b854c3357ce28e7a3879ba4ce Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 14:35:30 +0200 Subject: [PATCH 16/22] Convert `requestedAmount` to token precision --- src/hooks/tbtc/useFetchRedemptionDetails.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hooks/tbtc/useFetchRedemptionDetails.ts b/src/hooks/tbtc/useFetchRedemptionDetails.ts index 25c989fad..b33588661 100644 --- a/src/hooks/tbtc/useFetchRedemptionDetails.ts +++ b/src/hooks/tbtc/useFetchRedemptionDetails.ts @@ -10,8 +10,8 @@ import { useGetBlock } from "../../web3/hooks" import { isEmptyOrZeroAddress } from "../../web3/utils" interface RedemptionDetails { - requestedAmount: string - receivedAmount?: string + requestedAmount: string // in token precision + receivedAmount?: string // in satoshi redemptionRequestedTxHash: string redemptionCompletedTxHash?: { chain: string @@ -159,7 +159,11 @@ export const useFetchRedemptionDetails = ( requestedAt === redemptionRequestedEventTimestamp ) { setRedemptionData({ - requestedAmount: redemptionRequestedEvent.amount, + // TODO: Use satoshi <-> IERC20 conversion function from + // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 + requestedAmount: BigNumber.from(redemptionRequestedEvent.amount) + .mul(BigNumber.from(10).pow(10)) + .toString(), redemptionRequestedTxHash: redemptionRequestedEvent.txHash, redemptionCompletedTxHash: undefined, requestedAt: requestedAt, From d11a57edaeb92ee8f51fe2ad942829c2ee102f91 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 14:37:30 +0200 Subject: [PATCH 17/22] Set proper tokenSymbol to `requestedAmount` --- src/pages/tBTC/Bridge/UnmintDetails.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/tBTC/Bridge/UnmintDetails.tsx b/src/pages/tBTC/Bridge/UnmintDetails.tsx index cfbbbd142..32141c226 100644 --- a/src/pages/tBTC/Bridge/UnmintDetails.tsx +++ b/src/pages/tBTC/Bridge/UnmintDetails.tsx @@ -152,7 +152,7 @@ export const UnmintDetails: PageComponent = () => { Date: Fri, 14 Jul 2023 14:58:28 +0200 Subject: [PATCH 18/22] Covert treasuryFee to token precision Threshold Network Fee should be displayed as tBTC, not BTC. Because of that we are converting it to token precision. --- src/components/Modal/tBTC/InitiateUnminting.tsx | 3 +-- src/hooks/tbtc/useFetchRedemptionDetails.ts | 14 +++++++++++--- src/pages/tBTC/Bridge/UnmintDetails.tsx | 3 +-- src/threshold-ts/tbtc/index.ts | 9 ++++++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/components/Modal/tBTC/InitiateUnminting.tsx b/src/components/Modal/tBTC/InitiateUnminting.tsx index 609d455bf..fbb4e5210 100644 --- a/src/components/Modal/tBTC/InitiateUnminting.tsx +++ b/src/components/Modal/tBTC/InitiateUnminting.tsx @@ -108,8 +108,7 @@ const InitiateUnmintingBase: FC = ({ /> IERC20 conversion function from + // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 + treasuryFee: BigNumber.from(redemptionRequestedEvent.treasuryFee) + .mul(BigNumber.from(10).pow(10)) + .toString(), isTimedOut, }) return @@ -221,7 +225,11 @@ export const useFetchRedemptionDetails = ( }, requestedAt: redemptionRequestedEventTimestamp, completedAt: redemptionCompletedTimestamp, - treasuryFee: redemptionRequestedEvent.treasuryFee, + // TODO: Use satoshi <-> IERC20 conversion function from + // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 + treasuryFee: BigNumber.from(redemptionRequestedEvent.treasuryFee) + .mul(BigNumber.from(10).pow(10)) + .toString(), isTimedOut: false, btcAddress: createAddressFromOutputScript( scriptPubKey, diff --git a/src/pages/tBTC/Bridge/UnmintDetails.tsx b/src/pages/tBTC/Bridge/UnmintDetails.tsx index 32141c226..3c80ac5c0 100644 --- a/src/pages/tBTC/Bridge/UnmintDetails.tsx +++ b/src/pages/tBTC/Bridge/UnmintDetails.tsx @@ -325,8 +325,7 @@ const SuccessStep: FC<{ diff --git a/src/threshold-ts/tbtc/index.ts b/src/threshold-ts/tbtc/index.ts index 2400ecfe2..e8afe02f2 100644 --- a/src/threshold-ts/tbtc/index.ts +++ b/src/threshold-ts/tbtc/index.ts @@ -379,8 +379,8 @@ export interface ITBTC { * amount of BTC that will be redeemed. * @param redemptionAmount Amount of tbtc requested for redemption in ERC20 * standard. - * @returns Treasury fee and estimated amount of BTC that will be redeemed - * (both in satoshi). + * @returns Treasury fee (in token precision) and estimated amount of BTC that + * will be redeemed (in satoshi). */ getEstimatedRedemptionFees(redemptionAmount: string): Promise<{ treasuryFee: string @@ -1152,8 +1152,11 @@ export class TBTC implements ITBTC { redemptionAmountInSatoshi ).sub(treasuryFee) + // // TODO: Use satoshi <-> IERC20 conversion function from + //https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 + return { - treasuryFee: treasuryFee.toString(), + treasuryFee: treasuryFee.mul(BigNumber.from(10).pow(10)).toString(), estimatedAmountToBeReceived: estimatedAmountToBeReceived.toString(), } } From 696139be3debefb3e4c3abf0006f4bfc0249004b Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 15:08:02 +0200 Subject: [PATCH 19/22] Fix typo --- src/pages/tBTC/Bridge/UnmintDetails.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/tBTC/Bridge/UnmintDetails.tsx b/src/pages/tBTC/Bridge/UnmintDetails.tsx index 3c80ac5c0..1a4496d23 100644 --- a/src/pages/tBTC/Bridge/UnmintDetails.tsx +++ b/src/pages/tBTC/Bridge/UnmintDetails.tsx @@ -309,7 +309,7 @@ const SuccessStep: FC<{ From 0a8fcb4be697d91aca16fe6182eb8a86b309c5bb Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 15:28:34 +0200 Subject: [PATCH 20/22] Use `fromSatoshiToTokenPrecision` function --- src/hooks/tbtc/useFetchRedemptionDetails.ts | 33 ++++++++------------- src/threshold-ts/tbtc/index.ts | 5 +--- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/hooks/tbtc/useFetchRedemptionDetails.ts b/src/hooks/tbtc/useFetchRedemptionDetails.ts index 241b1eb45..75832f9c0 100644 --- a/src/hooks/tbtc/useFetchRedemptionDetails.ts +++ b/src/hooks/tbtc/useFetchRedemptionDetails.ts @@ -5,6 +5,7 @@ import { createAddressFromOutputScript, prependScriptPubKeyByLength, isValidType, + fromSatoshiToTokenPrecision, } from "../../threshold-ts/utils" import { useGetBlock } from "../../web3/hooks" import { isEmptyOrZeroAddress } from "../../web3/utils" @@ -159,20 +160,16 @@ export const useFetchRedemptionDetails = ( requestedAt === redemptionRequestedEventTimestamp ) { setRedemptionData({ - // TODO: Use satoshi <-> IERC20 conversion function from - // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 - requestedAmount: BigNumber.from(redemptionRequestedEvent.amount) - .mul(BigNumber.from(10).pow(10)) - .toString(), + requestedAmount: fromSatoshiToTokenPrecision( + redemptionRequestedEvent.amount + ).toString(), redemptionRequestedTxHash: redemptionRequestedEvent.txHash, redemptionCompletedTxHash: undefined, requestedAt: requestedAt, redemptionTimedOutTxHash: timedOutTxHash, - // TODO: Use satoshi <-> IERC20 conversion function from - // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 - treasuryFee: BigNumber.from(redemptionRequestedEvent.treasuryFee) - .mul(BigNumber.from(10).pow(10)) - .toString(), + treasuryFee: fromSatoshiToTokenPrecision( + redemptionRequestedEvent.treasuryFee + ).toString(), isTimedOut, }) return @@ -212,11 +209,9 @@ export const useFetchRedemptionDetails = ( redemptionCompletedBlockNumber ) setRedemptionData({ - // TODO: Use satoshi <-> IERC20 conversion function from - // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 - requestedAmount: BigNumber.from(redemptionRequestedEvent.amount) - .mul(BigNumber.from(10).pow(10)) - .toString(), + requestedAmount: fromSatoshiToTokenPrecision( + redemptionRequestedEvent.amount + ).toString(), receivedAmount: value.toString(), redemptionRequestedTxHash: redemptionRequestedEvent.txHash, redemptionCompletedTxHash: { @@ -225,11 +220,9 @@ export const useFetchRedemptionDetails = ( }, requestedAt: redemptionRequestedEventTimestamp, completedAt: redemptionCompletedTimestamp, - // TODO: Use satoshi <-> IERC20 conversion function from - // https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 - treasuryFee: BigNumber.from(redemptionRequestedEvent.treasuryFee) - .mul(BigNumber.from(10).pow(10)) - .toString(), + treasuryFee: fromSatoshiToTokenPrecision( + redemptionRequestedEvent.treasuryFee + ).toString(), isTimedOut: false, btcAddress: createAddressFromOutputScript( scriptPubKey, diff --git a/src/threshold-ts/tbtc/index.ts b/src/threshold-ts/tbtc/index.ts index a1045af00..17b5cab9e 100644 --- a/src/threshold-ts/tbtc/index.ts +++ b/src/threshold-ts/tbtc/index.ts @@ -1256,11 +1256,8 @@ export class TBTC implements ITBTC { redemptionAmountInSatoshi ).sub(treasuryFee) - // // TODO: Use satoshi <-> IERC20 conversion function from - //https://github.com/threshold-network/token-dashboard/commit/fe8b96e24e013c4e86e8faff74f4bc056fd3e0b4 - return { - treasuryFee: treasuryFee.mul(BigNumber.from(10).pow(10)).toString(), + treasuryFee: fromSatoshiToTokenPrecision(treasuryFee).toString(), estimatedAmountToBeReceived: estimatedAmountToBeReceived.toString(), } } From 316f5618aea9a01047a01e7fee227596bbbf5828 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 15:36:45 +0200 Subject: [PATCH 21/22] Cache `redemptionTreasuryFeeDivisor` This way we can reduce the number of requests. --- src/threshold-ts/tbtc/index.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/threshold-ts/tbtc/index.ts b/src/threshold-ts/tbtc/index.ts index 17b5cab9e..45735dc50 100644 --- a/src/threshold-ts/tbtc/index.ts +++ b/src/threshold-ts/tbtc/index.ts @@ -419,6 +419,8 @@ export class TBTC implements ITBTC { private _bitcoinConfig: BitcoinConfig private readonly _satoshiMultiplier = BigNumber.from(10).pow(10) + private _redemptionTreasuryFeeDivisor: BigNumber | undefined + constructor( ethereumConfig: EthereumConfig, bitcoinConfig: BitcoinConfig, @@ -1242,8 +1244,12 @@ export class TBTC implements ITBTC { const { satoshis: redemptionAmountInSatoshi } = this._amountToSatoshi(redemptionAmount) - const { redemptionTreasuryFeeDivisor } = - await this.bridgeContract.redemptionParameters() + const redemptionTreasuryFeeDivisor = + await this.getRedemptionTreasuryFeeDivisor() + + if (!redemptionTreasuryFeeDivisor) { + throw new Error("Redemption treasury fee divisor not found.") + } // https://github.com/keep-network/tbtc-v2/blob/main/solidity/contracts/bridge/Redemption.sol#L478 const treasuryFee = BigNumber.from(redemptionTreasuryFeeDivisor).gt(0) @@ -1261,4 +1267,14 @@ export class TBTC implements ITBTC { estimatedAmountToBeReceived: estimatedAmountToBeReceived.toString(), } } + + private getRedemptionTreasuryFeeDivisor = async () => { + if (!this._redemptionTreasuryFeeDivisor) { + const { redemptionTreasuryFeeDivisor } = + await this.bridgeContract.redemptionParameters() + this._redemptionTreasuryFeeDivisor = redemptionTreasuryFeeDivisor + } + + return this._redemptionTreasuryFeeDivisor + } } From 110264acd4b8345c2c120fe4fe81723ccfff6690 Mon Sep 17 00:00:00 2001 From: michalsmiarowski Date: Fri, 14 Jul 2023 16:20:11 +0200 Subject: [PATCH 22/22] Remove unnecessary comment --- src/pages/tBTC/Bridge/UnmintDetails.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/tBTC/Bridge/UnmintDetails.tsx b/src/pages/tBTC/Bridge/UnmintDetails.tsx index b4e6fc1bd..4053adfff 100644 --- a/src/pages/tBTC/Bridge/UnmintDetails.tsx +++ b/src/pages/tBTC/Bridge/UnmintDetails.tsx @@ -97,8 +97,6 @@ export const UnmintDetails: PageComponent = () => { }, [btcTxHash]) const isProcessCompleted = !!data?.redemptionCompletedTxHash?.bitcoin - // requested unmint amount of tBTC in satoshi!. This means that this value is - // the amount before subtracting the fees. const requestedAmount = data?.requestedAmount ?? "0" const receivedAmount = data?.receivedAmount ?? "0"