diff --git a/apps/bridge/src/components/Faq/index.tsx b/apps/bridge/src/components/Faq/index.tsx index f06fb398..4917263a 100644 --- a/apps/bridge/src/components/Faq/index.tsx +++ b/apps/bridge/src/components/Faq/index.tsx @@ -44,7 +44,7 @@ const faqList: Array = [ testnet. It provides a safe environment to try out the bridge functionality without any real token transactions. = [ ), value: "faq-5", }, - { - trigger: ( - - How are withdrawal fees determined? - - ), - content: ( -
- - The cost to claim on the bridge is dependent on the gas costs, - measured in Gwei, at the time of your transaction. The estimated - formula to determine this cost is: - - Cost (ETH)=600,000×Gwei - For example: -
    -
  • - - - At 15 Gwei, the cost is approximately 0.009 ETH. - -
  • -
  • - - - At 30 Gwei, the cost is approximately 0.018 ETH. - -
  • -
- - To minimize your costs, you can opt to claim during a period when the - Gwei is low. For current gas prices, you can check the{" "} -
- Etherscan Gas Tracker - - . - -
- ), - value: "faq-6", - }, { trigger: ( = [ ), - value: "faq-7", + value: "faq-6", }, ]; diff --git a/apps/bridge/src/components/bridge/CTA.tsx b/apps/bridge/src/components/bridge/CTA.tsx index 3a940c4f..1d981a89 100644 --- a/apps/bridge/src/components/bridge/CTA.tsx +++ b/apps/bridge/src/components/bridge/CTA.tsx @@ -21,6 +21,12 @@ import { useIsWalletMultisig } from "@hooks/useIsWalletMultisig"; import Link from "next/link"; import Image from "next/image"; +const tokensToRevoke = [ + "0xdac17f958d2ee523a2206206994597c13d831ec7", + // "0xa1cd76d0a3e122f689e6bec548155e842c4a06a1", + // sepolia testing +]; + // Contains a button & a modal to control allowance and deposits/withdrawals export default function CTA({ selected, @@ -117,6 +123,40 @@ export default function CTA({ ) ) { text = "Insufficient balance"; + } else if ( + tokensToRevoke.includes(selected.address.toLocaleLowerCase()) && + direction === Direction.Deposit && + fixDecimals(allowance).gt(0) && + fixDecimals(allowance).lt(fixDecimals(destinationTokenAmount || "0")) + ) { + text = ( +
+ {approvalStatus || "Reset allowance"} + {approvalStatus ? ( +
+ + Loading... +
+ ) : ( + "" + )} +
+ ); } else if ( fixDecimals(allowance || "-1").lt( fixDecimals(destinationTokenAmount || "0") @@ -173,6 +213,7 @@ export default function CTA({ chainId, approvalStatus, fixDecimals, + selected, ]); // set wagmi address to address for ssr @@ -233,6 +274,15 @@ export default function CTA({ onClick={() => { if (!isChainID) { switchToNetwork(chainId); + } else if ( + selected.address && + tokensToRevoke.includes(selected.address.toLocaleLowerCase()) && + fixDecimals(allowance).gt(0) && + fixDecimals(allowance).lt( + fixDecimals(destinationTokenAmount || "0") + ) + ) { + approve("0"); } else if ( fixDecimals(allowance || "-1").lt( fixDecimals(destinationTokenAmount || "0") diff --git a/apps/bridge/src/hooks/web3/bridge/read/useAllowanceCheck.ts b/apps/bridge/src/hooks/web3/bridge/read/useAllowanceCheck.ts index 3197cce9..5889d3f6 100644 --- a/apps/bridge/src/hooks/web3/bridge/read/useAllowanceCheck.ts +++ b/apps/bridge/src/hooks/web3/bridge/read/useAllowanceCheck.ts @@ -130,7 +130,7 @@ function useAllowanceCheck( resetAllowance, } as { allowance: string; - resetAllowance: () => void; + resetAllowance: () => Promise; }; } diff --git a/apps/bridge/src/hooks/web3/bridge/write/useCallApprove.tsx b/apps/bridge/src/hooks/web3/bridge/write/useCallApprove.tsx index 32be351a..4e2f9a32 100644 --- a/apps/bridge/src/hooks/web3/bridge/write/useCallApprove.tsx +++ b/apps/bridge/src/hooks/web3/bridge/write/useCallApprove.tsx @@ -23,54 +23,68 @@ export function useCallApprove(selected: Token) { }); // construct a method to call and await an approval call to allocate allowance to the bridge - const approve = useCallback(async () => { - try { - // mark as waiting... - setApprovalStatus("Waiting for tx approval..."); - // perform the tx call - const txRes = await writeApprove?.({ - args: [ - bridgeAddress as `0x${string}`, - BigInt( - parseUnits( - destinationTokenAmount || "1", - selected.decimals - ).toString() - ), - ], - }).catch((e) => { - throw e; - }); - // mark approval... - setApprovalStatus("Tx approved, waiting for confirmation..."); - // wait for one confirmation - await provider - .waitForTransaction(txRes?.hash || "", 1) - .catch((e: any) => { + const approve = useCallback( + async (overwriteAmount?: string) => { + try { + // mark as waiting... + setApprovalStatus("Waiting for tx approval..."); + // perform the tx call + const txRes = await writeApprove?.({ + args: [ + bridgeAddress as `0x${string}`, + BigInt( + parseUnits( + overwriteAmount || destinationTokenAmount || "1", + selected.decimals + ).toString() + ), + ], + }).catch((e) => { throw e; }); - // final update - setApprovalStatus("Tx settled"); - } catch { - // log the approval was cancelled - setApprovalStatus("Approval cancelled"); - } finally { - // call this to reset the allowance in the ui - resetAllowance(); - // stop awaiting - setApprovalStatus(false); - } + // mark approval... + setApprovalStatus("Tx approved, waiting for confirmation..."); + // wait for one confirmation + await provider + .waitForTransaction(txRes?.hash || "", 1) + .catch((e: any) => { + throw e; + }); - // token is now approved - return true; - }, [ - bridgeAddress, - destinationTokenAmount, - provider, - selected.decimals, - resetAllowance, - writeApprove, - ]); + // final update + setApprovalStatus("Tx settled"); + + // delay for rpc update + await new Promise((resolve: (value: unknown) => void) => { + setTimeout(() => { + resolve(true); + }, 6000); + }); + } catch { + // log the approval was cancelled + setApprovalStatus("Approval cancelled"); + } finally { + // call this to reset the allowance in the ui + console.log("reseting allowance"); + await resetAllowance(); + console.log("reset allowance done"); + + // stop awaiting + setApprovalStatus(false); + } + + // token is now approved + return true; + }, + [ + bridgeAddress, + destinationTokenAmount, + provider, + selected.decimals, + resetAllowance, + writeApprove, + ] + ); return { approvalStatus, diff --git a/apps/bridge/src/hooks/web3/bridge/write/useWaitForRelay.tsx b/apps/bridge/src/hooks/web3/bridge/write/useWaitForRelay.tsx index 4efa3823..9d118295 100644 --- a/apps/bridge/src/hooks/web3/bridge/write/useWaitForRelay.tsx +++ b/apps/bridge/src/hooks/web3/bridge/write/useWaitForRelay.tsx @@ -375,7 +375,7 @@ export function useWaitForRelay({ direction }: { direction: Direction }) { // if we got a receipt then we can reset everything and return if (receipt.status) { // call this to reset the allowance and balances in the ui - resetAllowance(); + await resetAllowance(); resetBalances(); } diff --git a/apps/bridge/src/providers/stateContext.tsx b/apps/bridge/src/providers/stateContext.tsx index b385502b..991b373d 100644 --- a/apps/bridge/src/providers/stateContext.tsx +++ b/apps/bridge/src/providers/stateContext.tsx @@ -130,7 +130,7 @@ export type StateProps = { }) => void; setSafeChains: (chains: number[]) => void; resetBalances: () => void; - resetAllowance: () => void; + resetAllowance: () => Promise; refetchWithdrawals: () => void; refetchDeposits: () => void; loadMoreWithdrawals: () => void; @@ -381,6 +381,10 @@ export function StateProvider({ children }: { children: React.ReactNode }) { provider ); + useEffect(() => { + console.log({ allowance }); + }, [allowance]); + // fetch the gas estimate for the selected operation on in the selected direction const { actualGasFee, resetGasEstimate } = useGasEstimate( chainId, @@ -471,10 +475,13 @@ export function StateProvider({ children }: { children: React.ReactNode }) { // reset the allowances and balances once we gather enough intel to make the calls useEffect( () => { - resetAllowance(); - resetBalances(); - refetchL1FeeData(); - refetchL2FeeData(); + const reset = async () => { + await resetAllowance(); + resetBalances(); + refetchL1FeeData(); + refetchL2FeeData(); + }; + reset(); }, // eslint-disable-next-line react-hooks/exhaustive-deps [chainId, client?.address, selectedToken, multicall, bridgeAddress]