Skip to content

Commit

Permalink
refactor actions token approve, small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
KorbinianK committed Oct 30, 2023
1 parent f29cb7d commit 80311cd
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 91 deletions.
56 changes: 23 additions & 33 deletions packages/bridge-ui-v2/src/components/Bridge/Actions.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import { t } from 'svelte-i18n';
import { routingContractsMap } from '$bridgeConfig';
import { Button } from '$components/Button';
import { Icon } from '$components/Icon';
import { bridges, type RequireApprovalArgs } from '$libs/bridge';
import { bridges, ContractType,type RequireApprovalArgs } from '$libs/bridge';
import type { ERC721Bridge } from '$libs/bridge/ERC721Bridge';
import type { ERC1155Bridge } from '$libs/bridge/ERC1155Bridge';
import { getContractAddressBasedOnType } from '$libs/bridge/getContractAddressBasedOnType';
import { type NFT, TokenType } from '$libs/token';
import { checkOwnershipOfNFT } from '$libs/token/checkOwnership';
import { getConnectedWallet } from '$libs/util/getConnectedWallet';
Expand Down Expand Up @@ -49,7 +49,6 @@
//TODO: this should probably be checked somewhere else?
export async function checkTokensApproved() {
$validatingAmount = true;
if ($selectedToken?.type === TokenType.ERC721 || $selectedToken?.type === TokenType.ERC1155) {
if ($account?.address && $network?.id && $destNetwork?.id) {
const currentChainId = $network?.id;
Expand All @@ -63,20 +62,32 @@
}
const wallet = await getConnectedWallet();
const { erc1155VaultAddress, erc721VaultAddress } = routingContractsMap[currentChainId][destinationChainId];
const spenderAddress = getContractAddressBasedOnType({
srcChainId: currentChainId,
destChainId: destinationChainId,
tokenType: token.type,
contractType: ContractType.VAULT,
});
if (!spenderAddress) {
throw new Error('No spender address found');
}
const args: RequireApprovalArgs = {
tokenAddress: token.addresses[currentChainId],
owner: wallet.account.address,
spenderAddress,
tokenId: BigInt(token.tokenId),
chainId: currentChainId,
};
if (token.type === TokenType.ERC1155) {
try {
const bridge = bridges[token.type] as ERC1155Bridge;
// Let's check if the vault is approved for all ERC1155
const result = await bridge.isApprovedForAll({
tokenAddress: token.addresses[currentChainId],
owner: wallet.account.address,
spenderAddress: erc1155VaultAddress,
tokenId: BigInt(token.tokenId),
chainId: currentChainId,
});
const result = await bridge.isApprovedForAll(args);
allTokensApproved = result;
} catch (error) {
console.error('isApprovedForAll error');
Expand All @@ -86,25 +97,16 @@
// Let's check if the vault is approved for all ERC721
try {
const args: RequireApprovalArgs = {
tokenAddress: token.addresses[currentChainId],
owner: wallet.account.address,
spenderAddress: erc721VaultAddress,
tokenId: BigInt(token.tokenId),
chainId: currentChainId,
};
const requiresApproval = await bridge.requiresApproval(args);
allTokensApproved = !requiresApproval;
} catch (error) {
console.error('isApprovedForAll error');
}
}
}
}
$validatingAmount = false;
}
// TODO: feels like we need a state machine here
// Basic conditions so we can even start the bridging process
Expand Down Expand Up @@ -180,18 +182,6 @@
: commonConditions;
</script>

bridging {bridging}<br />
balance {hasBalance}<br />
validating {$validatingAmount}<br />
insufficientAllowance {$insufficientAllowance}<br /><br />

canDoNothing {canDoNothing} <br />
$insufficientAllowance {insufficientAllowance} <br />
commonConditions {commonConditions}
enteredAmount {$enteredAmount}<br />
tokenBalance {$tokenBalance}<br />
enteredAmount {#if $enteredAmount}test
{/if}<br />
<div class="f-between-center w-full gap-4">
{#if $selectedToken && $selectedToken.type !== TokenType.ETH}
<Button
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-ui-v2/src/components/Bridge/Amount.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
if ($selectedToken.type === TokenType.ERC1155) {
// For ERC1155, no decimals are allowed
if (value.includes('.') || value.includes(',')) {
if (/[.,]/.test(value)) {
invalidInput = true;
return;
}
Expand Down
11 changes: 6 additions & 5 deletions packages/bridge-ui-v2/src/components/Bridge/NFTBridge.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { routingContractsMap } from '$bridgeConfig';
import { chainConfig } from '$chainConfig';
import { ImportMethod } from '$components/Bridge/types';
import { Button } from '$components/Button';
import { Card } from '$components/Card';
import { ChainSelectorWrapper } from '$components/ChainSelector';
Expand Down Expand Up @@ -54,7 +55,7 @@
let recipientStepComponent: RecipientStep;
let processingFeeComponent: ProcessingFee;
let actionsComponent: Actions;
let importMethod: 'scan' | 'manual' = 'scan';
let importMethod: ImportMethod;
let nftIdArray: number[] = [];
let contractAddress: Address | string = '';
Expand Down Expand Up @@ -94,7 +95,7 @@
function updateForm() {
tick().then(() => {
if (importMethod === 'manual') {
if (importMethod === ImportMethod.MANUAL) {
// run validations again if we are in manual mode
runValidations();
} else {
Expand Down Expand Up @@ -256,7 +257,7 @@
if (nftIdInputComponent) nftIdInputComponent.clearIds();
$selectedToken = ETHToken;
importMethod === 'scan';
importMethod === ImportMethod.SCAN;
scanned = false;
canProceed = false;
$selectedNFTs = [];
Expand Down Expand Up @@ -295,7 +296,7 @@
};
const changeImportMethod = () => {
importMethod = importMethod === 'manual' ? 'scan' : 'manual';
importMethod = importMethod === ImportMethod.MANUAL ? ImportMethod.SCAN : ImportMethod.MANUAL;
resetForm();
};
Expand Down Expand Up @@ -403,7 +404,7 @@
</button>
</div>
{:else if activeStep === NFTSteps.IMPORT}
{#if importMethod === 'manual'}
{#if importMethod === ImportMethod.MANUAL}
<div class="h-sep" />

<div class="f-col w-full">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
import {
destNetwork as destinationChain,
enteredAmount,
insufficientBalance,
selectedNFTs,
selectedToken,
tokenBalance,
} from '$components/Bridge/state';
import { ImportMethod } from '$components/Bridge/types';
import { Button } from '$components/Button';
import { ChainSelectorWrapper } from '$components/ChainSelector';
import { IconFlipper } from '$components/Icon';
Expand All @@ -34,7 +37,7 @@
export let nftIdArray: number[] = [];
export let canProceed: boolean = false;
export let scanned: boolean;
export let importMethod: 'scan' | 'manual';
export let importMethod: ImportMethod = ImportMethod.SCAN;
export let foundNFTs: NFT[] = [];
export let validating: boolean = false;
export let contractAddress: Address | string = '';
Expand Down Expand Up @@ -92,7 +95,7 @@
const changeImportMethod = () => {
if (addressInputComponent) addressInputComponent.clearAddress();
importMethod = importMethod === 'manual' ? 'scan' : 'manual';
importMethod = importMethod === ImportMethod.MANUAL ? ImportMethod.SCAN : ImportMethod.MANUAL;
scanned = false;
$selectedNFTs = [];
$selectedToken = null;
Expand Down Expand Up @@ -184,37 +187,43 @@
$: canImport = $account?.isConnected && $network?.id && $destinationChain && !scanning;
// Handles the next step button status
$: if (importMethod === 'manual') {
if (
$: {
const hasSelectedNFTs = $selectedNFTs !== null && $selectedNFTs !== undefined && $selectedNFTs.length > 0;
if (!hasSelectedNFTs) canProceed = false;
const isValidManualERC721 =
detectedTokenType === TokenType.ERC721 &&
addressInputState === AddressInputState.VALID &&
idInputState === IDInputState.VALID &&
isOwnerOfAllToken
) {
canProceed = true;
} else if (
isOwnerOfAllToken;
const isValidManualERC1155 =
detectedTokenType === TokenType.ERC1155 &&
addressInputState === AddressInputState.VALID &&
idInputState === IDInputState.VALID &&
$enteredAmount > BigInt(0) &&
isOwnerOfAllToken
) {
canProceed = true;
} else {
canProceed = false;
}
} else if (importMethod === 'scan' && $selectedNFTs && $selectedNFTs.length > 0 && $destinationChain && scanned) {
if ($selectedNFTs && $selectedNFTs[0].type === TokenType.ERC1155) {
if ($enteredAmount > BigInt(0)) {
canProceed = true;
} else {
canProceed = false;
}
} else if ($selectedNFTs && $selectedNFTs[0].type === TokenType.ERC721) {
canProceed = true;
}
} else {
canProceed = false;
isOwnerOfAllToken;
const isManualImportValid = importMethod === ImportMethod.MANUAL && (isValidManualERC721 || isValidManualERC1155);
const isValidScanERC1155 =
hasSelectedNFTs &&
$selectedNFTs![0].type === TokenType.ERC1155 &&
$enteredAmount > BigInt(0) &&
typeof $tokenBalance === 'bigint' &&
$enteredAmount <= $tokenBalance &&
!$insufficientBalance;
const isValidScanERC721 = hasSelectedNFTs && $selectedNFTs![0].type === TokenType.ERC721;
const isScanImportValid =
importMethod === ImportMethod.SCAN &&
hasSelectedNFTs &&
$destinationChain !== undefined && // Assuming undefined is invalid
scanned &&
(isValidScanERC1155 || isValidScanERC721);
canProceed = isManualImportValid || isScanImportValid;
}
$: isDisabled = idInputState !== IDInputState.VALID || addressInputState !== AddressInputState.VALID;
Expand All @@ -223,11 +232,11 @@
<div class="f-between-center gap-4">
<ChainSelectorWrapper />
</div>

<!--
Manual NFT Input
-->

{#if importMethod === 'manual'}
{#if importMethod === ImportMethod.MANUAL}
<div id="manualImport">
<AddressInput
bind:this={addressInputComponent}
Expand Down
5 changes: 5 additions & 0 deletions packages/bridge-ui-v2/src/components/Bridge/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ export enum NFTSteps {
CONFIRM,
}

export enum ImportMethod {
MANUAL,
SCAN,
}

export type BridgeType = BridgeTypes;
40 changes: 17 additions & 23 deletions packages/bridge-ui-v2/src/libs/bridge/checkBalanceToBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@ import { fetchBalance, getPublicClient } from '@wagmi/core';
import { type Address, zeroAddress } from 'viem';

import { routingContractsMap } from '$bridgeConfig';
import {
InsufficientAllowanceError,
InsufficientBalanceError,
NotApprovedError,
RevertedWithFailedError,
} from '$libs/error';
import { InsufficientAllowanceError, InsufficientBalanceError, RevertedWithFailedError } from '$libs/error';
import { getAddress, type Token, TokenType } from '$libs/token';
import { isDeployedCrossChain } from '$libs/token/isDeployedCrossChain';
import { getConnectedWallet } from '$libs/util/getConnectedWallet';

import { bridges } from './bridges';
import { ERC20Bridge } from './ERC20Bridge';
import { ERC1155Bridge } from './ERC1155Bridge';
import { estimateCostOfBridging } from './estimateCostOfBridging';
import type { BridgeArgs, ERC20BridgeArgs, ERC1155BridgeArgs, ETHBridgeArgs } from './types';

Expand Down Expand Up @@ -103,22 +97,22 @@ export async function checkBalanceToBridge({
)
throw new InsufficientBalanceError('you do not have enough balance to bridge');

const bridge = bridges[token.type];

if (bridge instanceof ERC1155Bridge) {
// Let's check if the vault is approved for all ERC1155
const isApprovedForAll = await bridge.isApprovedForAll({
tokenAddress,
owner: wallet.account.address,
spenderAddress: erc1155VaultAddress,
tokenId: 0n,
chainId: srcChainId,
});

if (!isApprovedForAll) {
throw new NotApprovedError(`Not approved for all for token`);
}
}
// const bridge = bridges[token.type];

// if (bridge instanceof ERC1155Bridge) {
// // Let's check if the vault is approved for all ERC1155
// const isApprovedForAll = await bridge.isApprovedForAll({
// tokenAddress,
// owner: wallet.account.address,
// spenderAddress: erc1155VaultAddress,
// tokenId: 0n,
// chainId: srcChainId,
// });

// if (!isApprovedForAll) {
// throw new NotApprovedError(`Not approved for all for token`);
// }
// }

const isTokenAlreadyDeployed = await isDeployedCrossChain({
token,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { expect } from 'chai';

import { routingContractsMap } from '$bridgeConfig';
import { ContractType, type GetContractAddressType } from '$libs/bridge';
import { TokenType } from '$libs/token';

import { getContractAddressBasedOnType } from './getContractAddressBasedOnType';

const SRC_CHAIN_ID = 1;
const DEST_CHAIN_ID = 2;

describe('getContractAddressBasedOnType', () => {
it('should return the correct contract address based on contract type', () => {
// Given
const args: GetContractAddressType = {
srcChainId: SRC_CHAIN_ID,
destChainId: DEST_CHAIN_ID,
tokenType: TokenType.ERC20,
contractType: ContractType.BRIDGE,
};

const expectedAddress = routingContractsMap[SRC_CHAIN_ID][DEST_CHAIN_ID].bridgeAddress;

// When
const address = getContractAddressBasedOnType(args);

// Then
expect(address).to.equal(expectedAddress);
});
});
Loading

0 comments on commit 80311cd

Please sign in to comment.