From 4092dc147e347c07c2a967f0779ebca78fef8cf8 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Wed, 10 Jan 2024 13:58:01 +0100 Subject: [PATCH 1/5] Return deposit data from the handlers --- src/contracts/Router.sol | 15 ++++++--------- src/contracts/handlers/ERC20Handler.sol | 6 ++++-- .../handlers/PermissionlessGenericHandler.sol | 3 ++- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/contracts/Router.sol b/src/contracts/Router.sol index 1a4907ca..09ecd64b 100644 --- a/src/contracts/Router.sol +++ b/src/contracts/Router.sol @@ -37,8 +37,7 @@ contract Router is Context { bytes32 resourceID, uint64 depositNonce, address indexed user, - bytes data, - bytes handlerResponse + bytes data ); modifier onlyAllowed() { @@ -82,16 +81,13 @@ contract Router is Context { @param feeData Additional data to be passed to the fee handler. @notice Emits {Deposit} event with all necessary parameters and a handler response. @return depositNonce deposit nonce for the destination domain. - @return handlerResponse a handler response: - - ERC20Handler: responds with an empty data. - - PermissionlessGenericHandler: responds with an empty data. */ function deposit( uint8 destinationDomainID, bytes32 resourceID, bytes calldata depositData, bytes calldata feeData - ) external payable whenBridgeNotPaused returns (uint64 depositNonce, bytes memory handlerResponse) { + ) external payable whenBridgeNotPaused returns (uint64 depositNonce) { if (destinationDomainID == _domainID) revert DepositToCurrentDomain(); address sender = _msgSender(); @@ -114,10 +110,11 @@ contract Router is Context { depositNonce = ++_depositCounts[destinationDomainID]; + IHandler depositHandler = IHandler(handler); - handlerResponse = depositHandler.deposit(resourceID, sender, depositData); + bytes memory handlerDepositData = depositHandler.deposit(resourceID, sender, depositData); - emit Deposit(destinationDomainID, resourceID, depositNonce, sender, depositData, handlerResponse); - return (depositNonce, handlerResponse); + emit Deposit(destinationDomainID, resourceID, depositNonce, sender, handlerDepositData); + return depositNonce; } } diff --git a/src/contracts/handlers/ERC20Handler.sol b/src/contracts/handlers/ERC20Handler.sol index e072fda6..cef72171 100755 --- a/src/contracts/handlers/ERC20Handler.sol +++ b/src/contracts/handlers/ERC20Handler.sol @@ -45,7 +45,9 @@ contract ERC20Handler is IHandler, ERCHandlerHelpers, ERC20Safe { bytes calldata data ) external override onlyBridge returns (bytes memory) { uint256 amount; - (amount) = abi.decode(data, (uint)); + uint256 destinationRecipientAddressLen; + bytes memory destinationRecipientAddress; + (amount, destinationRecipientAddressLen, destinationRecipientAddress) = abi.decode(data, (uint256, uint256, bytes)); address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; if (!_tokenContractAddressToTokenProperties[tokenAddress].isWhitelisted) @@ -57,7 +59,7 @@ contract ERC20Handler is IHandler, ERCHandlerHelpers, ERC20Safe { lockERC20(tokenAddress, depositor, address(this), amount); } - return abi.encodePacked(convertToInternalBalance(tokenAddress, amount)); + return abi.encode(convertToInternalBalance(tokenAddress, amount), destinationRecipientAddressLen, destinationRecipientAddress); } /** diff --git a/src/contracts/handlers/PermissionlessGenericHandler.sol b/src/contracts/handlers/PermissionlessGenericHandler.sol index 65fba51c..302f93de 100755 --- a/src/contracts/handlers/PermissionlessGenericHandler.sol +++ b/src/contracts/handlers/PermissionlessGenericHandler.sol @@ -109,7 +109,7 @@ contract PermissionlessGenericHandler is IHandler { After this, the target contract will get the following: executeFuncSignature(address executionDataDepositor, uint[] uintArray, address addr) */ - function deposit(bytes32 resourceID, address depositor, bytes calldata data) external view returns (bytes memory) { + function deposit(bytes32 resourceID, address depositor, bytes calldata data) external pure returns (bytes memory) { require(data.length >= 76, "Incorrect data length"); // 32 + 2 + 1 + 1 + 20 + 20 uint256 maxFee; @@ -141,6 +141,7 @@ contract PermissionlessGenericHandler is IHandler { require(maxFee < MAX_FEE, "requested fee too large"); require(depositor == executionDataDepositor, "incorrect depositor in deposit data"); + return data; } /** From e2da8124c4e5247653619c63a005c778b82a4a3b Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Wed, 10 Jan 2024 15:13:35 +0100 Subject: [PATCH 2/5] FIx ERC20 handler data deconstruction --- src/contracts/handlers/ERC20Handler.sol | 5 +++-- src/contracts/handlers/ERCHandlerHelpers.sol | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/contracts/handlers/ERC20Handler.sol b/src/contracts/handlers/ERC20Handler.sol index cef72171..c014a9e0 100755 --- a/src/contracts/handlers/ERC20Handler.sol +++ b/src/contracts/handlers/ERC20Handler.sol @@ -47,7 +47,8 @@ contract ERC20Handler is IHandler, ERCHandlerHelpers, ERC20Safe { uint256 amount; uint256 destinationRecipientAddressLen; bytes memory destinationRecipientAddress; - (amount, destinationRecipientAddressLen, destinationRecipientAddress) = abi.decode(data, (uint256, uint256, bytes)); + (amount, destinationRecipientAddressLen) = abi.decode(data, (uint, uint)); + destinationRecipientAddress = bytes(data[64:64 + destinationRecipientAddressLen]); address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; if (!_tokenContractAddressToTokenProperties[tokenAddress].isWhitelisted) @@ -59,7 +60,7 @@ contract ERC20Handler is IHandler, ERCHandlerHelpers, ERC20Safe { lockERC20(tokenAddress, depositor, address(this), amount); } - return abi.encode(convertToInternalBalance(tokenAddress, amount), destinationRecipientAddressLen, destinationRecipientAddress); + return abi.encodePacked(convertToInternalBalance(tokenAddress, amount), destinationRecipientAddressLen, destinationRecipientAddress); } /** diff --git a/src/contracts/handlers/ERCHandlerHelpers.sol b/src/contracts/handlers/ERCHandlerHelpers.sol index 427480fd..e97f22d6 100755 --- a/src/contracts/handlers/ERCHandlerHelpers.sol +++ b/src/contracts/handlers/ERCHandlerHelpers.sol @@ -121,17 +121,17 @@ contract ERCHandlerHelpers is IERCHandler { @param tokenAddress Address of contract to be used when executing proposals. @param amount Decimals value to be set for {contractAddress}. */ - function convertToInternalBalance(address tokenAddress, uint256 amount) internal view returns (bytes memory) { + function convertToInternalBalance(address tokenAddress, uint256 amount) internal view returns (uint256) { Decimals memory decimals = _tokenContractAddressToTokenProperties[tokenAddress].decimals; uint256 convertedBalance; if (!decimals.isSet) { - return ""; + return amount; } else if (decimals.externalDecimals >= DEFAULT_DECIMALS) { convertedBalance = amount / (10 ** (decimals.externalDecimals - DEFAULT_DECIMALS)); } else { convertedBalance = amount * (10 ** (DEFAULT_DECIMALS - decimals.externalDecimals)); } - return abi.encodePacked(convertedBalance); + return convertedBalance; } } From a8e437ea2ce25e97fc1174dd9c170fd736e3d72c Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Wed, 10 Jan 2024 15:26:05 +0100 Subject: [PATCH 3/5] Update tests --- test/contractBridge/depositERC20.test.ts | 2 - .../decimals/bothChainsNot18Decimals.test.ts | 34 +++++---------- .../decimals/oneChainNot18Decimals.test.ts | 14 +------ .../decimals/oneChainWith0Decimals.test.ts | 14 +------ test/e2e/erc20/decimals/roundingLoss.test.ts | 42 ++++++------------- test/handlers/erc20/deposit.test.ts | 2 - test/handlers/fee/basic/collectFee.test.ts | 2 - .../fee/percentage/collectFee.test.ts | 2 - .../generic/permissionlessDeposit.test.ts | 1 - test/helpers.ts | 18 ++++---- 10 files changed, 35 insertions(+), 96 deletions(-) diff --git a/test/contractBridge/depositERC20.test.ts b/test/contractBridge/depositERC20.test.ts index 360e987c..184b87d6 100755 --- a/test/contractBridge/depositERC20.test.ts +++ b/test/contractBridge/depositERC20.test.ts @@ -188,7 +188,6 @@ describe("Bridge - [deposit - ERC20]", () => { expectedDepositNonce, await depositorAccount.getAddress(), depositData.toLowerCase(), - "0x", ); const depositTx2 = routerInstance @@ -203,7 +202,6 @@ describe("Bridge - [deposit - ERC20]", () => { expectedDepositNonce + 1, await depositorAccount.getAddress(), depositData.toLowerCase(), - "0x", ); }); diff --git a/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts b/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts index ed5ba478..6c292863 100755 --- a/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts +++ b/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts @@ -206,6 +206,9 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18", () => { await expect(originDepositTx).not.to.be.reverted; + const originExpectedDepositData = + toHex(relayerConvertedAmount.toString(), 32) + + originDepositData.substring(66); // check that deposited amount converted to 18 decimal places is // emitted in handlerResponse await expect(originDepositTx) @@ -215,23 +218,13 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18", () => { originResourceID.toLowerCase(), expectedDepositNonce, await depositorAccount.getAddress(), - originDepositData.toLowerCase(), - toHex(relayerConvertedAmount.toString(), 32), - ); - - // this mocks depositProposal data for executing on - // destination chain which is returned from relayers - const originDepositProposalData = - await createDepositProposalDataFromHandlerResponse( - originDepositTx, - 20, - await recipientAccount.getAddress(), + originExpectedDepositData.toLowerCase(), ); const originDomainProposal = { originDomainID: originDomainID, depositNonce: expectedDepositNonce, - data: originDepositProposalData, + data: originExpectedDepositData, resourceID: destinationResourceID, }; @@ -282,6 +275,9 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18", () => { ); await expect(destinationDepositTx).not.to.be.reverted; + const destinationExepectedDepositData = + toHex(relayerConvertedAmount.toString(), 32) + + destinationDepositData.substring(66); // check that deposited amount converted to 18 decimal places is // emitted in handlerResponse await expect(destinationDepositTx) @@ -291,23 +287,13 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18", () => { destinationResourceID.toLowerCase(), expectedDepositNonce, await recipientAccount.getAddress(), - destinationDepositData.toLowerCase(), - toHex(relayerConvertedAmount.toString(), 32), - ); - - // this mocks depositProposal data for executing on - // destination chain which is returned from relayers - const destinationDepositProposalData = - await createDepositProposalDataFromHandlerResponse( - destinationDepositTx, - 20, - await depositorAccount.getAddress(), + destinationExepectedDepositData.toLowerCase(), ); const destinationDomainProposal = { originDomainID: destinationDomainID, depositNonce: expectedDepositNonce, - data: destinationDepositProposalData, + data: destinationExepectedDepositData, resourceID: originResourceID, }; diff --git a/test/e2e/erc20/decimals/oneChainNot18Decimals.test.ts b/test/e2e/erc20/decimals/oneChainNot18Decimals.test.ts index 14e10118..9ebd6ac7 100755 --- a/test/e2e/erc20/decimals/oneChainNot18Decimals.test.ts +++ b/test/e2e/erc20/decimals/oneChainNot18Decimals.test.ts @@ -8,7 +8,7 @@ import { deployBridgeContracts, createResourceID, createERCDepositData, - createDepositProposalDataFromHandlerResponse, + getDepositEventData, } from "../../../helpers"; import type { Bridge, @@ -224,19 +224,10 @@ describe("E2E ERC20 - Two EVM Chains, one with decimal places == 18, other with ); await expect(originDepositTx).not.to.be.reverted; - // this mocks depositProposal data for executing on - // destination chain which is returned from relayers - const originDepositProposalData = - await createDepositProposalDataFromHandlerResponse( - originDepositTx, - 20, - await recipientAccount.getAddress(), - ); - const originDomainProposal = { originDomainID: originDomainID, depositNonce: expectedDepositNonce, - data: originDepositProposalData, + data: await getDepositEventData(originDepositTx), resourceID: destinationResourceID, }; @@ -297,7 +288,6 @@ describe("E2E ERC20 - Two EVM Chains, one with decimal places == 18, other with expectedDepositNonce, await recipientAccount.getAddress(), destinationDepositData.toLowerCase(), - "0x", ); // Recipient should have a balance of 0 (deposit amount) diff --git a/test/e2e/erc20/decimals/oneChainWith0Decimals.test.ts b/test/e2e/erc20/decimals/oneChainWith0Decimals.test.ts index 80fcc067..92424cec 100755 --- a/test/e2e/erc20/decimals/oneChainWith0Decimals.test.ts +++ b/test/e2e/erc20/decimals/oneChainWith0Decimals.test.ts @@ -8,7 +8,7 @@ import { deployBridgeContracts, createResourceID, createERCDepositData, - createDepositProposalDataFromHandlerResponse, + getDepositEventData, } from "../../../helpers"; import type { Bridge, @@ -226,19 +226,10 @@ describe("E2E ERC20 - Two EVM Chains, one with decimal places == 18, other with await expect(originDepositTx).not.to.be.reverted; - // this mocks depositProposal data for executing on - // destination chain which is returned from relayers - const originDepositProposalData = - await createDepositProposalDataFromHandlerResponse( - originDepositTx, - 20, - await recipientAccount.getAddress(), - ); - const originDomainProposal = { originDomainID: originDomainID, depositNonce: expectedDepositNonce, - data: originDepositProposalData, + data: getDepositEventData(originDepositTx), resourceID: destinationResourceID, }; @@ -299,7 +290,6 @@ describe("E2E ERC20 - Two EVM Chains, one with decimal places == 18, other with expectedDepositNonce, await recipientAccount.getAddress(), destinationDepositData.toLowerCase(), - "0x", ); // Recipient should have a balance of 0 (deposit amount) diff --git a/test/e2e/erc20/decimals/roundingLoss.test.ts b/test/e2e/erc20/decimals/roundingLoss.test.ts index 08fbae28..944d890c 100755 --- a/test/e2e/erc20/decimals/roundingLoss.test.ts +++ b/test/e2e/erc20/decimals/roundingLoss.test.ts @@ -9,7 +9,7 @@ import { createResourceID, createERCDepositData, toHex, - createDepositProposalDataFromHandlerResponse, + getDepositEventData, } from "../../../helpers"; import type { Bridge, @@ -216,8 +216,10 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18 with roundin ); await expect(originDepositTx).not.to.be.reverted; - // check that deposited amount converted to 18 decimal places is - // emitted in handlerResponse + // check that deposited amount converted to 18 decimal places is emitted in data + const originExpectedDepositAmount = + toHex(originRelayerConvertedAmount.toString(), 32) + + originDepositData.substring(66); await expect(originDepositTx) .to.emit(originRouterInstance, "Deposit") .withArgs( @@ -225,23 +227,13 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18 with roundin originResourceID.toLowerCase(), expectedDepositNonce, await depositorAccount.getAddress(), - originDepositData.toLowerCase(), - toHex(originRelayerConvertedAmount.toString(), 32), - ); - - // this mocks depositProposal data for executing on - // destination chain which is returned from relayers - const originDepositProposalData = - await createDepositProposalDataFromHandlerResponse( - originDepositTx, - 20, - await recipientAccount.getAddress(), + originExpectedDepositAmount.toLowerCase(), ); const originDomainProposal = { originDomainID: originDomainID, depositNonce: expectedDepositNonce, - data: originDepositProposalData, + data: getDepositEventData(originDepositTx), resourceID: destinationResourceID, }; @@ -292,8 +284,10 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18 with roundin ); await expect(destinationDepositTx).not.to.be.reverted; - // check that deposited amount converted to 18 decimal places is - // emitted in handlerResponse + // check that deposited amount converted to 18 decimal places is emitted in data + const destinationExpectedDepositData = + toHex(destinationRelayerConvertedAmount.toString(), 32) + + destinationDepositData.substring(66); await expect(destinationDepositTx) .to.emit(destinationRouterInstance, "Deposit") .withArgs( @@ -301,23 +295,13 @@ describe("E2E ERC20 - Two EVM Chains both with decimal places != 18 with roundin destinationResourceID, expectedDepositNonce, await recipientAccount.getAddress(), - destinationDepositData.toLowerCase(), - toHex(destinationRelayerConvertedAmount.toString(), 32), - ); - - // this mocks depositProposal data for executing on - // destination chain which is returned from relayers - const destinationDepositProposalData = - await createDepositProposalDataFromHandlerResponse( - destinationDepositTx, - 20, - await depositorAccount.getAddress(), + destinationExpectedDepositData.toLowerCase(), ); const destinationDomainProposal = { originDomainID: destinationDomainID, depositNonce: expectedDepositNonce, - data: destinationDepositProposalData, + data: await getDepositEventData(destinationDepositTx), resourceID: originResourceID, }; diff --git a/test/handlers/erc20/deposit.test.ts b/test/handlers/erc20/deposit.test.ts index dbad58fb..c82047e1 100755 --- a/test/handlers/erc20/deposit.test.ts +++ b/test/handlers/erc20/deposit.test.ts @@ -118,7 +118,6 @@ describe("ERC20Handler - [Deposit ERC20]", () => { lenRecipientAddress, recipientAccount, ).toLowerCase(), - "0x", ); }); @@ -151,7 +150,6 @@ describe("ERC20Handler - [Deposit ERC20]", () => { lenRecipientAddress, recipientAccount, ), - "0x", ); }); diff --git a/test/handlers/fee/basic/collectFee.test.ts b/test/handlers/fee/basic/collectFee.test.ts index d6770d61..b389c462 100755 --- a/test/handlers/fee/basic/collectFee.test.ts +++ b/test/handlers/fee/basic/collectFee.test.ts @@ -195,7 +195,6 @@ describe("BasicFeeHandler - [collectFee]", () => { expectedDepositNonce, await depositorAccount.getAddress(), erc20depositData.toLowerCase(), - "0x", ); await expect(depositTx) @@ -415,7 +414,6 @@ describe("BasicFeeHandler - [collectFee]", () => { expectedDepositNonce, await depositorAccount.getAddress(), erc20depositData.toLowerCase(), - "0x", ); await expect(depositTx) diff --git a/test/handlers/fee/percentage/collectFee.test.ts b/test/handlers/fee/percentage/collectFee.test.ts index 84460ca0..1ac1a664 100755 --- a/test/handlers/fee/percentage/collectFee.test.ts +++ b/test/handlers/fee/percentage/collectFee.test.ts @@ -141,7 +141,6 @@ describe("PercentageFeeHandler - [collectFee]", () => { expectedDepositNonce, await depositorAccount.getAddress(), depositData.toLowerCase(), - "0x", ); await expect(depositTx) @@ -269,7 +268,6 @@ describe("PercentageFeeHandler - [collectFee]", () => { expectedDepositNonce, await depositorAccount.getAddress(), depositData.toLowerCase(), - "0x", ); await expect(depositTx) diff --git a/test/handlers/generic/permissionlessDeposit.test.ts b/test/handlers/generic/permissionlessDeposit.test.ts index 5de7c20b..35762c0a 100755 --- a/test/handlers/generic/permissionlessDeposit.test.ts +++ b/test/handlers/generic/permissionlessDeposit.test.ts @@ -99,7 +99,6 @@ describe("PermissionlessGenericHandler - [deposit]", () => { expectedDepositNonce, await depositorAccount.getAddress(), depositData.toLowerCase(), - "0x", ); }); diff --git a/test/helpers.ts b/test/helpers.ts index 43f8a5c3..18bf211e 100755 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only import { ethers } from "hardhat"; -import type { TransactionResponse } from "ethers"; +import type { TransactionReceipt, TransactionResponse } from "ethers"; import { generateAccessControlFuncSignatures } from "../scripts/utils"; import type { Bridge, Router, Executor } from "../typechain-types"; @@ -126,16 +126,14 @@ export async function deployBridgeContracts( return [bridgeInstance, routerInstance, executorInstance]; } -export async function createDepositProposalDataFromHandlerResponse( +export async function getDepositEventData( depositTx: TransactionResponse, - lenRecipientAddress: number, - recipientAccount: string, ): Promise { - return createERCDepositData( - BigInt((await depositTx.wait(1)).logs[2]["args"][5]).toString(), - lenRecipientAddress, - recipientAccount, - ); + return ( + ((await depositTx.wait(1)) as TransactionReceipt).logs[2] as unknown as { + args: string[]; + } + )["args"][4]; } // This helper can be used to prepare execution data for PermissionlessGenericHandler @@ -170,6 +168,6 @@ module.exports = { createResourceID, decimalToPaddedBinary, deployBridgeContracts, - createDepositProposalDataFromHandlerResponse, createPermissionlessGenericExecutionData, + getDepositEventData, }; From f05566373cedfe2f6179699dafa1089412b8dfec Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Wed, 10 Jan 2024 15:26:36 +0100 Subject: [PATCH 4/5] Update solidity docs --- src/contracts/Router.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/Router.sol b/src/contracts/Router.sol index 09ecd64b..cd265022 100644 --- a/src/contracts/Router.sol +++ b/src/contracts/Router.sol @@ -79,7 +79,7 @@ contract Router is Context { @param resourceID ResourceID used to find address of handler to be used for deposit. @param depositData Additional data to be passed to specified handler. @param feeData Additional data to be passed to the fee handler. - @notice Emits {Deposit} event with all necessary parameters and a handler response. + @notice Emits {Deposit} event with all necessary parameters. @return depositNonce deposit nonce for the destination domain. */ function deposit( From f3d61443b40d5c41b6ffdab82584399b9a844eee Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Wed, 10 Jan 2024 15:32:21 +0100 Subject: [PATCH 5/5] Lint --- src/contracts/handlers/ERC20Handler.sol | 6 +++++- test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/contracts/handlers/ERC20Handler.sol b/src/contracts/handlers/ERC20Handler.sol index c014a9e0..6998d56c 100755 --- a/src/contracts/handlers/ERC20Handler.sol +++ b/src/contracts/handlers/ERC20Handler.sol @@ -60,7 +60,11 @@ contract ERC20Handler is IHandler, ERCHandlerHelpers, ERC20Safe { lockERC20(tokenAddress, depositor, address(this), amount); } - return abi.encodePacked(convertToInternalBalance(tokenAddress, amount), destinationRecipientAddressLen, destinationRecipientAddress); + return abi.encodePacked( + convertToInternalBalance(tokenAddress, amount), + destinationRecipientAddressLen, + destinationRecipientAddress + ); } /** diff --git a/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts b/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts index 6c292863..ea987523 100755 --- a/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts +++ b/test/e2e/erc20/decimals/bothChainsNot18Decimals.test.ts @@ -8,7 +8,6 @@ import { deployBridgeContracts, createResourceID, createERCDepositData, - createDepositProposalDataFromHandlerResponse, toHex, } from "../../../helpers"; import type {