Skip to content

Commit

Permalink
update checks
Browse files Browse the repository at this point in the history
  • Loading branch information
KorbinianK committed May 10, 2024
1 parent 87f0318 commit 49e872a
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
import { pendingTransactions } from '$stores/pendingTransactions';
import { ClaimConfirmStep, ReviewStep } from '../Shared';
import ClaimPreCheck from '../Shared/ClaimPreCheck.svelte';
import { ClaimAction } from '../Shared/types';
import { DialogStep, DialogStepper } from '../Stepper';
import ClaimStepNavigation from './ClaimStepNavigation.svelte';
import ClaimPreCheck from './ClaimSteps/ClaimPreCheck.svelte';
import { ClaimSteps, INITIAL_STEP } from './types';
const log = getLogger('ClaimDialog');
Expand Down Expand Up @@ -171,8 +171,6 @@
claimingDone = false;
};
let checkingPrerequisites: boolean;
let previousStep: ClaimSteps;
$: if (activeStep !== previousStep) {
previousStep = activeStep;
Expand Down Expand Up @@ -202,7 +200,7 @@
isActive={activeStep === ClaimSteps.CONFIRM}>{$t('bridge.step.confirm.title')}</DialogStep>
</DialogStepper>
{#if activeStep === ClaimSteps.CHECK}
<ClaimPreCheck tx={bridgeTx} bind:canContinue {checkingPrerequisites} bind:hideContinueButton />
<ClaimPreCheck tx={bridgeTx} bind:canContinue bind:hideContinueButton />
{:else if activeStep === ClaimSteps.REVIEW}
<ReviewStep tx={bridgeTx} {nft} />
{:else if activeStep === ClaimSteps.CONFIRM}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import Claim from '../Claim.svelte';
import { ClaimConfirmStep, ReviewStep } from '../Shared';
import ClaimPreCheck from '../Shared/ClaimPreCheck.svelte';
import { ClaimAction } from '../Shared/types';
import RetryStepNavigation from './RetryStepNavigation.svelte';
import RetryOptionStep from './RetrySteps/RetryOptionStep.svelte';
Expand All @@ -34,14 +35,16 @@
const dialogId = `dialog-${uid()}`;
export let activeStep: RetrySteps = RetrySteps.SELECT;
export let activeStep: RetrySteps = INITIAL_STEP;
let canContinue = false;
let retrying: boolean;
let retryDone = false;
let ClaimComponent: Claim;
let isDesktopOrLarger = false;
let hideContinueButton = false;
let txHash: Hash;
const handleRetryError = () => {
Expand Down Expand Up @@ -116,6 +119,10 @@

<div class="w-full h-full f-col">
<DialogStepper>
<DialogStep
stepIndex={RetrySteps.CHECK}
currentStepIndex={activeStep}
isActive={activeStep === RetrySteps.CHECK}>{$t('transactions.claim.steps.pre_check.title')}</DialogStep>
<DialogStep
stepIndex={RetrySteps.SELECT}
currentStepIndex={activeStep}
Expand All @@ -130,7 +137,9 @@
isActive={activeStep === RetrySteps.CONFIRM}>{$t('common.confirm')}</DialogStep>
</DialogStepper>

{#if activeStep === RetrySteps.SELECT}
{#if activeStep === RetrySteps.CHECK}
<ClaimPreCheck tx={bridgeTx} bind:canContinue bind:hideContinueButton />
{:else if activeStep === RetrySteps.SELECT}
<RetryOptionStep bind:canContinue />
{:else if activeStep === RetrySteps.REVIEW}
<ReviewStep bind:tx={bridgeTx} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
export const enum RetrySteps {
CHECK,
SELECT,
REVIEW,
CONFIRM,
}

export const INITIAL_STEP = RetrySteps.SELECT;
export const INITIAL_STEP = RetrySteps.CHECK;

export const enum RetryStatus {
PENDING,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
<script lang="ts">
import { getBalance, readContract, switchChain } from '@wagmi/core';
import { getBalance, switchChain } from '@wagmi/core';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
import { type Address, parseEther, zeroAddress } from 'viem';
import { type Address, parseEther } from 'viem';
import { quotaManagerAbi } from '$abi';
import { ActionButton } from '$components/Button';
import { Icon } from '$components/Icon';
import Spinner from '$components/Spinner/Spinner.svelte';
import { Tooltip } from '$components/Tooltip';
import { claimConfig } from '$config';
import { type BridgeTransaction, ContractType } from '$libs/bridge';
import { getContractAddressByType } from '$libs/bridge/getContractAddressByType';
import { type BridgeTransaction } from '$libs/bridge';
import { checkBridgeQuota } from '$libs/bridge/checkBridgeQuota';
import { getChainName, isL2Chain } from '$libs/chain';
import { config } from '$libs/wagmi';
import { account } from '$stores/account';
import { connectedSourceChain, switchingNetwork } from '$stores/network';
export let tx: BridgeTransaction;
export let canContinue = false;
export let checkingPrerequisites: boolean;
export let hideContinueButton = false;
let checkingPrerequisites: boolean;
const switchChains = async () => {
$switchingNetwork = true;
try {
Expand All @@ -39,78 +40,35 @@
const balance = await getBalance(config, { address, chainId });
if (balance.value <= parseEther(String(claimConfig.minimumEthToClaim))) {
hasEnoughEth = false;
} else {
hasEnoughEth = true;
}
};
const checkBridgeQuota = async ({
srcChainId,
destChainId,
tokenAddress = zeroAddress,
amount,
}: {
srcChainId: number;
destChainId: number;
tokenAddress?: Address;
amount: bigint;
}) => {
if (isL2Chain(Number(tx.destChainId))) {
// Quota only applies for transactions from L2-L1.
// So if the destination chain is not an L2 chain, we can skip this check.
hasEnoughEth = true;
return;
}
const quotaManagerAddress = getContractAddressByType({
srcChainId,
destChainId,
contractType: ContractType.QUOTAMANAGER,
});
const quota = await readContract(config, {
address: quotaManagerAddress,
abi: quotaManagerAbi,
chainId: Number(tx.destChainId),
functionName: 'availableQuota',
args: [tokenAddress, 0n],
});
if (amount > quota) {
hasEnoughQuota = false;
} else {
hasEnoughQuota = true;
if (balance.value >= parseEther(String(claimConfig.minimumEthToClaim))) {
return true;
}
return false;
};
const checkConditions = async () => {
checkingPrerequisites = true;
const checks = Promise.allSettled([
const results = await Promise.allSettled([
checkEnoughBalance($account.address, Number(tx.destChainId)),
checkBridgeQuota({
srcChainId: Number(tx.destChainId), // The destination chain is the source chain for the quota manager
destChainId: Number(tx.srcChainId),
tokenAddress: tx.canonicalTokenAddress,
transaction: tx,
amount: tx.amount,
}),
]);
try {
const results = await checks;
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
// eslint-disable-next-line no-console
console.log(`Promise ${index} resolved with value:`, result.value);
} else {
// eslint-disable-next-line no-console
console.log(`Promise ${index} rejected with reason:`, result.reason);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
if (index === 0) {
hasEnoughEth = result.value;
} else if (index === 1) {
hasEnoughQuota = result.value;
}
});
} catch (error) {
console.error('Unexpected error:', error);
}
} else {
// You can log or handle errors here if a promise was rejected.
console.error(`Error in promise at index ${index}:`, result.reason);
}
});
checkingPrerequisites = false;
};
Expand All @@ -130,10 +88,14 @@
canContinue = false;
}
$: $account && tx.destChainId, checkConditions();
$: $account && checkConditions();
$: hasEnoughEth = false;
$: hasEnoughQuota = false;
onMount(() => {
checkConditions();
});
</script>

<div class="space-y-[25px] mt-[20px]">
Expand All @@ -146,9 +108,9 @@
<div class="f-row gap-1">
<span class="text-secondary-content">{$t('transactions.claim.steps.pre_check.chain_check')}</span>
<Tooltip>
<h2>What is "Connected to the correct chain"?</h2>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe error soluta ut accusantium in doloremque commodi
et earum nisi quisquam quo placeat rerum exercitationem minus optio, voluptate architecto officiis consequatur!
<h2>{$t('transactions.claim.steps.pre_check.tooltip.chain.title')}</h2>

<span>{$t('transactions.claim.steps.pre_check.tooltip.chain.description')}</span>
</Tooltip>
</div>

Expand All @@ -164,9 +126,8 @@
<div class="f-row gap-1">
<span class="text-secondary-content">{$t('transactions.claim.steps.pre_check.funds_check')}</span>
<Tooltip>
<h2>What is "Sufficient funds"?</h2>
You need to have enough funds on the destination chain to pay for the transaction fees in order to claim. If
you paid the processing fee, wait for the relayer to claim it for you.
<h2>{$t('transactions.claim.steps.pre_check.tooltip.funds.title')}</h2>
<span>{$t('transactions.claim.steps.pre_check.tooltip.funds.description')} </span>
</Tooltip>
</div>
{#if checkingPrerequisites}
Expand All @@ -177,17 +138,15 @@
<Icon type="x-close-circle" fillClass="fill-negative-sentiment" />
{/if}
</div>
{#if isL2Chain(Number(tx.destChainId))}
{#if isL2Chain(Number(tx.srcChainId))}
<div class="f-between-center">
<div class="f-row gap-1">
<span class="text-secondary-content">{$t('transactions.claim.steps.pre_check.quota_check')}</span>
<Tooltip>
<h2>What is "Sufficient daily quota"?</h2>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Explicabo, sint. Quo quidem hic accusantium eaque
esse cupiditate rerum velit pariatur ab eligendi repellat, iusto aliquam id, dolorum animi ducimus earum.
<h2>{$t('transactions.claim.steps.pre_check.tooltip.quota.title')}</h2>
<span>{$t('transactions.claim.steps.pre_check.tooltip.quota.description')} </span>
</Tooltip>
</div>

{#if checkingPrerequisites}
<Spinner />
{:else if hasEnoughQuota}
Expand Down
16 changes: 15 additions & 1 deletion packages/bridge-ui/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,21 @@
"ready": "You can continue with the claim process!",
"step": "Claim step",
"switch_chain": "This transaction is bridging to <span class=\"font-bold text-primary\">{chain}</span> You need to be connected to this chain",
"title": "Requirements"
"title": "Requirements",
"tooltip": {
"chain": {
"description": "You need to be connected to the chain you want to bridge your funds to.",
"title": "What is \"Connected to the correct chain\"?"
},
"funds": {
"description": "In order to claim the transaction yourself, you need enough funds on the destination chain. If you've kept the default processing fee, the relayer will likely claim for you soon.",
"title": "What is \"Sufficient funds to claim\"?"
},
"quota": {
"description": "Currently there is a daily limit of how much ETH can be bridged to L1. If the quota is reached, please try again the next day.",
"title": "What is \"Sufficient daily quota\"?"
}
}
},
"review": {
"name": "Review",
Expand Down
10 changes: 6 additions & 4 deletions packages/bridge-ui/src/libs/bridge/ETHBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ export class ETHBridge extends Bridge {
id: BigInt(0), // will be set in contract
};

const minGasLimit = await bridgeContract.read.getMessageMinGasLimit([0n]);
log('Min gas limit for message', minGasLimit);
if (processingFee !== 0n) {
const minGasLimit = await bridgeContract.read.getMessageMinGasLimit([0n]);
log('Min gas limit for message', minGasLimit);

const gasLimit = minGasLimit + 1;
message.gasLimit = gasLimit;
const gasLimit = minGasLimit + 1;
message.gasLimit = gasLimit;
}

log('Preparing transaction with message', message);

Expand Down
63 changes: 63 additions & 0 deletions packages/bridge-ui/src/libs/bridge/checkBridgeQuota.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { readContract } from '@wagmi/core';
import { type Address, zeroAddress } from 'viem';

import { quotaManagerAbi } from '$abi';
import { isL2Chain } from '$libs/chain';
import { getLogger } from '$libs/util/logger';
import { config } from '$libs/wagmi';

import { type BridgeTransaction, ContractType } from '.';
import { getContractAddressByType } from './getContractAddressByType';

const log = getLogger('bridge:checkBridgeQuota');

export const checkBridgeQuota = async ({
transaction,
amount,
}: {
transaction: BridgeTransaction;
tokenAddress?: Address;
amount: bigint;
}) => {
log(
'Checking bridge quota',
transaction.canonicalTokenAddress,
amount,
isL2Chain(Number(transaction.destChainId)),
transaction.destChainId,
transaction.srcChainId,
);

const tokenAddress =
transaction.canonicalTokenAddress && (transaction.canonicalTokenAddress as string) !== ''
? transaction.canonicalTokenAddress
: zeroAddress;

if (isL2Chain(Number(transaction.destChainId))) {
// Quota only applies for transactions from L2-L1.
// So if the destination chain is an L2 chain, we can skip this check.
log('Skipping quota check for L2 chain');
return true;
}

const quotaManagerAddress = getContractAddressByType({
srcChainId: Number(transaction.destChainId),
destChainId: Number(transaction.srcChainId),
contractType: ContractType.QUOTAMANAGER,
});

const quota = await readContract(config, {
address: quotaManagerAddress,
abi: quotaManagerAbi,
chainId: Number(transaction.destChainId),
functionName: 'availableQuota',
args: [tokenAddress, 0n],
});

if (amount > quota) {
log('Not enough quota', quota, amount);
return false;
}
log('Quota:', quota, 'Amount:', amount, 'Has enough quota:', amount <= quota);
return true;
};

0 comments on commit 49e872a

Please sign in to comment.