From 5b1b544d1d603219fd73a357dac8e16b49c4bfbf Mon Sep 17 00:00:00 2001 From: Foivos Date: Mon, 23 Dec 2024 17:11:03 +0200 Subject: [PATCH 1/7] Added the basic changes. --- DESIGN.md | 2 ++ contracts/TokenHandler.sol | 22 +++++----------------- test/InterchainTokenFactory.js | 12 ++++++++---- test/InterchainTokenService.js | 2 +- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index a9187a40..aae5c644 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -41,6 +41,8 @@ Most current bridge designs aim to transfer a pre-existing, popular token to dif We designed an [interface](./contracts/interfaces/IInterchainTokenStandard.sol) along with an [example implementation](./contracts/interchain-token/InterchainTokenStandard.sol) of an ERC20 that can use the `InterchainTokenService` internally. This has the main benefit that for `TokenManagers` that require user approval (Lock/Unlock, Lock/Unlock Fee and Mint/BurnFrom), the token can provide this approval within the same call, providing better UX for users, and saving them some gas. +Interchain Tokens function the same as mint/burn tokens do: The `tokenManager` that manages them will ask them to `burn` tokens on the sending chain, and to `mint` tokens on the receiving chain. + ## Interchain Communication Spec The messages going through the Axelar Network between `InterchainTokenServices` need to have a consistent format to be understood properly. We chose to use `abi` encoding because it is easy to use in EVM chains, which are at the front and center of programmable blockchains, and because it is easy to implement in other ecosystems which tend to be more gas efficient. There are currently three supported message types: `INTERCHAIN_TRANSFER`, `DEPLOY_INTERCHAIN_TOKEN`, `DEPLOY_TOKEN_MANAGER`. diff --git a/contracts/TokenHandler.sol b/contracts/TokenHandler.sol index be794e9a..b5fa88b8 100644 --- a/contracts/TokenHandler.sol +++ b/contracts/TokenHandler.sol @@ -13,6 +13,7 @@ import { ITokenManager } from './interfaces/ITokenManager.sol'; import { ITokenManagerProxy } from './interfaces/ITokenManagerProxy.sol'; import { IERC20MintableBurnable } from './interfaces/IERC20MintableBurnable.sol'; import { IERC20BurnableFrom } from './interfaces/IERC20BurnableFrom.sol'; +import { IMinter } from './interfaces/IMinter.sol'; /** * @title TokenHandler @@ -39,12 +40,7 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea /// @dev Track the flow amount being received via the message ITokenManager(tokenManager).addFlowIn(amount); - if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) { - _giveInterchainToken(tokenAddress, to, amount); - return (amount, tokenAddress); - } - - if (tokenManagerType == uint256(TokenManagerType.MINT_BURN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) { + if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) { _mintToken(tokenManager, tokenAddress, to, amount); return (amount, tokenAddress); } @@ -77,9 +73,7 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea if (tokenOnly && msg.sender != tokenAddress) revert NotToken(msg.sender, tokenAddress); - if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) { - _takeInterchainToken(tokenAddress, from, amount); - } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN)) { + if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN)) { _burnToken(tokenManager, tokenAddress, from, amount); } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) { _burnTokenFrom(tokenAddress, from, amount); @@ -138,6 +132,8 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) { ITokenManager(tokenManager).approveService(); + } else if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) { + IMinter(ITokenManager(tokenManager).tokenAddress()).transferMintership(tokenManager); } } @@ -161,14 +157,6 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea return diff < amount ? diff : amount; } - function _giveInterchainToken(address tokenAddress, address to, uint256 amount) internal { - IERC20(tokenAddress).safeCall(abi.encodeWithSelector(IERC20MintableBurnable.mint.selector, to, amount)); - } - - function _takeInterchainToken(address tokenAddress, address from, uint256 amount) internal { - IERC20(tokenAddress).safeCall(abi.encodeWithSelector(IERC20MintableBurnable.burn.selector, from, amount)); - } - function _mintToken(address tokenManager, address tokenAddress, address to, uint256 amount) internal { ITokenManager(tokenManager).mintToken(tokenAddress, to, amount); } diff --git a/test/InterchainTokenFactory.js b/test/InterchainTokenFactory.js index fa9e687e..da105371 100644 --- a/test/InterchainTokenFactory.js +++ b/test/InterchainTokenFactory.js @@ -197,7 +197,7 @@ describe('InterchainTokenFactory', () => { const checkRoles = async (tokenManager, minter) => { const token = await getContractAt('InterchainToken', await tokenManager.tokenAddress(), wallet); expect(await token.isMinter(minter)).to.be.true; - expect(await token.isMinter(service.address)).to.be.true; + expect(await token.isMinter(tokenManager.address)).to.be.true; expect(await tokenManager.isOperator(minter)).to.be.true; expect(await tokenManager.isOperator(service.address)).to.be.true; @@ -328,7 +328,11 @@ describe('InterchainTokenFactory', () => { .and.to.emit(tokenManager, 'RolesRemoved') .withArgs(tokenFactory.address, 1 << OPERATOR_ROLE) .and.to.emit(tokenManager, 'RolesRemoved') - .withArgs(tokenFactory.address, 1 << FLOW_LIMITER_ROLE); + .withArgs(tokenFactory.address, 1 << FLOW_LIMITER_ROLE) + .and.to.emit(token, 'RolesRemoved') + .withArgs(service.address, 1 << MINTER_ROLE) + .and.to.emit(token, 'RolesAdded') + .withArgs(tokenManager.address, 1 << MINTER_ROLE); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes'], @@ -384,7 +388,7 @@ describe('InterchainTokenFactory', () => { }, ), tokenFactory, - 'InvalidMinter', + 'NotMinter', [service.address], ); @@ -437,7 +441,7 @@ describe('InterchainTokenFactory', () => { }, ), tokenFactory, - 'InvalidMinter', + 'NotMinter', [service.address], ); diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index 2cb75946..401edf33 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -646,7 +646,7 @@ describe('Interchain Token Service', () => { const token = await getContractAt('InterchainToken', tokenAddress, wallet); expect(await token.isMinter(wallet.address)).to.be.true; - expect(await token.isMinter(service.address)).to.be.true; + expect(await token.isMinter(tokenManager.address)).to.be.true; }); it('Should revert when registering an interchain token as a lock/unlock for a second time', async () => { From 3be2fda56967e584765853629f1fbe99b2f62744 Mon Sep 17 00:00:00 2001 From: Foivos Date: Thu, 2 Jan 2025 11:28:29 +0200 Subject: [PATCH 2/7] made lint happy --- contracts/TokenHandler.sol | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/contracts/TokenHandler.sol b/contracts/TokenHandler.sol index b5fa88b8..d7e36209 100644 --- a/contracts/TokenHandler.sol +++ b/contracts/TokenHandler.sol @@ -11,7 +11,6 @@ import { Create3AddressFixed } from './utils/Create3AddressFixed.sol'; import { ITokenManagerType } from './interfaces/ITokenManagerType.sol'; import { ITokenManager } from './interfaces/ITokenManager.sol'; import { ITokenManagerProxy } from './interfaces/ITokenManagerProxy.sol'; -import { IERC20MintableBurnable } from './interfaces/IERC20MintableBurnable.sol'; import { IERC20BurnableFrom } from './interfaces/IERC20BurnableFrom.sol'; import { IMinter } from './interfaces/IMinter.sol'; @@ -40,7 +39,11 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea /// @dev Track the flow amount being received via the message ITokenManager(tokenManager).addFlowIn(amount); - if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) { + if ( + tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || + tokenManagerType == uint256(TokenManagerType.MINT_BURN) || + tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM) + ) { _mintToken(tokenManager, tokenAddress, to, amount); return (amount, tokenAddress); } @@ -73,7 +76,9 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea if (tokenOnly && msg.sender != tokenAddress) revert NotToken(msg.sender, tokenAddress); - if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN)) { + if ( + tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN) + ) { _burnToken(tokenManager, tokenAddress, from, amount); } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) { _burnTokenFrom(tokenAddress, from, amount); From de537141064dd2a8040841f4f4435317d2c1b972 Mon Sep 17 00:00:00 2001 From: Foivos Date: Fri, 10 Jan 2025 12:07:41 +0200 Subject: [PATCH 3/7] addressed comments --- .changeset/many-tigers-kneel.md | 5 +++++ contracts/TokenHandler.sol | 28 ++++++++++++++------------ contracts/interfaces/ITokenHandler.sol | 4 +++- 3 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 .changeset/many-tigers-kneel.md diff --git a/.changeset/many-tigers-kneel.md b/.changeset/many-tigers-kneel.md new file mode 100644 index 00000000..a17c7f28 --- /dev/null +++ b/.changeset/many-tigers-kneel.md @@ -0,0 +1,5 @@ +--- +'@axelar-network/interchain-token-service': minor +--- + +Interchain tokens now get minted/burnt by the token manager. diff --git a/contracts/TokenHandler.sol b/contracts/TokenHandler.sol index 5db715f6..61660fc8 100644 --- a/contracts/TokenHandler.sol +++ b/contracts/TokenHandler.sol @@ -43,7 +43,7 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea tokenManagerType == uint256(TokenManagerType.MINT_BURN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM) ) { - _mintToken(tokenManager, tokenAddress, to, amount); + _mintToken(ITokenManager(tokenManager), tokenAddress, to, amount); return (amount, tokenAddress); } @@ -78,7 +78,7 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea if ( tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || tokenManagerType == uint256(TokenManagerType.MINT_BURN) ) { - _burnToken(tokenManager, tokenAddress, from, amount); + _burnToken(ITokenManager(tokenManager), tokenAddress, from, amount); } else if (tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM)) { _burnTokenFrom(tokenAddress, from, amount); } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK)) { @@ -132,13 +132,15 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea * @param tokenManager The address of the token manager. */ // slither-disable-next-line locked-ether - function postTokenManagerDeploy(uint256 tokenManagerType, address tokenManager) external payable { - // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf - if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) { - ITokenManager(tokenManager).approveService(); - } else if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) { - IMinter(ITokenManager(tokenManager).tokenAddress()).transferMintership(tokenManager); - } + function postTokenManagerDeploy(uint256 tokenManagerType, ITokenManager tokenManager) external payable { + // For native interhcain tokens we transfer mintership to the token manager. + // This is done here because InterchainToken bytecode needs to be fixed. + if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) { + IMinter(tokenManager.tokenAddress()).transferMintership(address(tokenManager)); + // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf. + } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) { + tokenManager.approveService(); + } } function _transferTokenFrom(address tokenAddress, address from, address to, uint256 amount) internal { @@ -161,12 +163,12 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea return diff < amount ? diff : amount; } - function _mintToken(address tokenManager, address tokenAddress, address to, uint256 amount) internal { - ITokenManager(tokenManager).mintToken(tokenAddress, to, amount); + function _mintToken(ITokenManager tokenManager, address tokenAddress, address to, uint256 amount) internal { + tokenManager.mintToken(tokenAddress, to, amount); } - function _burnToken(address tokenManager, address tokenAddress, address from, uint256 amount) internal { - ITokenManager(tokenManager).burnToken(tokenAddress, from, amount); + function _burnToken(ITokenManager tokenManager, address tokenAddress, address from, uint256 amount) internal { + tokenManager.burnToken(tokenAddress, from, amount); } function _burnTokenFrom(address tokenAddress, address from, uint256 amount) internal { diff --git a/contracts/interfaces/ITokenHandler.sol b/contracts/interfaces/ITokenHandler.sol index 7650de21..4d697b9b 100644 --- a/contracts/interfaces/ITokenHandler.sol +++ b/contracts/interfaces/ITokenHandler.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.0; +import { ITokenManager } from './ITokenManager.sol'; + /** * @title ITokenHandler Interface * @notice This interface is responsible for handling tokens before initiating an interchain token transfer, or after receiving one. @@ -47,5 +49,5 @@ interface ITokenHandler { * @param tokenManagerType The token manager type. * @param tokenManager The address of the token manager. */ - function postTokenManagerDeploy(uint256 tokenManagerType, address tokenManager) external payable; + function postTokenManagerDeploy(uint256 tokenManagerType, ITokenManager tokenManager) external payable; } From 5bcb97a181767e5bfe30177d3725d1fe2ba72e16 Mon Sep 17 00:00:00 2001 From: Foivos Date: Fri, 10 Jan 2025 12:52:10 +0200 Subject: [PATCH 4/7] prettier --- contracts/TokenHandler.sol | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contracts/TokenHandler.sol b/contracts/TokenHandler.sol index 61660fc8..244c9d7c 100644 --- a/contracts/TokenHandler.sol +++ b/contracts/TokenHandler.sol @@ -137,10 +137,12 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea // This is done here because InterchainToken bytecode needs to be fixed. if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) { IMinter(tokenManager.tokenAddress()).transferMintership(address(tokenManager)); - // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf. - } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) { + // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf. + } else if ( + tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE) + ) { tokenManager.approveService(); - } + } } function _transferTokenFrom(address tokenAddress, address from, address to, uint256 amount) internal { From 2a606ecdb2237cee3eace46ad350e0503e2b1f1c Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 10 Jan 2025 10:44:21 -0500 Subject: [PATCH 5/7] Apply suggestions from code review --- .changeset/many-tigers-kneel.md | 2 +- contracts/TokenHandler.sol | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/many-tigers-kneel.md b/.changeset/many-tigers-kneel.md index a17c7f28..0742f1cf 100644 --- a/.changeset/many-tigers-kneel.md +++ b/.changeset/many-tigers-kneel.md @@ -2,4 +2,4 @@ '@axelar-network/interchain-token-service': minor --- -Interchain tokens now get minted/burnt by the token manager. +Interchain tokens now get minted/burnt by the token manager to be consistent with custom tokens diff --git a/contracts/TokenHandler.sol b/contracts/TokenHandler.sol index 244c9d7c..baabe92d 100644 --- a/contracts/TokenHandler.sol +++ b/contracts/TokenHandler.sol @@ -133,8 +133,8 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea */ // slither-disable-next-line locked-ether function postTokenManagerDeploy(uint256 tokenManagerType, ITokenManager tokenManager) external payable { - // For native interhcain tokens we transfer mintership to the token manager. - // This is done here because InterchainToken bytecode needs to be fixed. + // For native interchain tokens, we transfer mintership to the token manager. + // This is done here because the InterchainToken bytecode is preferred to be fixed to avoid having multiple versions of the Token code used in production. if (tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN)) { IMinter(tokenManager.tokenAddress()).transferMintership(address(tokenManager)); // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf. From 74a38f0e2a1481fe6c914fc5a8f43ba9d96ca4fd Mon Sep 17 00:00:00 2001 From: Foivos Date: Wed, 15 Jan 2025 18:29:49 +0200 Subject: [PATCH 6/7] remove old tests --- test/InterchainTokenService.js | 82 ---------------------------------- 1 file changed, 82 deletions(-) diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index 1c837ff9..74bb275d 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -687,53 +687,6 @@ describe('Interchain Token Service', () => { const salt = getRandomBytes32(); let tokenManager; - it('Should register an interchain token', async () => { - const tokenId = await service.interchainTokenId(wallet.address, salt); - const tokenAddress = await service.interchainTokenAddress(tokenId); - const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, tokenAddress]); - const expectedTokenManagerAddress = await service.tokenManagerAddress(tokenId); - - await expect( - reportGas( - service.deployInterchainToken(salt, '', tokenName, tokenSymbol, tokenDecimals, wallet.address, 0), - 'Call deployInterchainToken on source chain', - ), - ) - .to.emit(service, 'InterchainTokenIdClaimed') - .withArgs(tokenId, wallet.address, salt) - .to.emit(service, 'InterchainTokenDeployed') - .withArgs(tokenId, tokenAddress, wallet.address, tokenName, tokenSymbol, tokenDecimals) - .to.emit(service, 'TokenManagerDeployed') - .withArgs(tokenId, expectedTokenManagerAddress, NATIVE_INTERCHAIN_TOKEN, params); - - const tokenManagerAddress = await service.deployedTokenManager(tokenId); - expect(tokenManagerAddress).to.not.equal(AddressZero); - - tokenManager = await getContractAt('TokenManager', tokenManagerAddress, wallet); - expect(await tokenManager.isOperator(wallet.address)).to.be.true; - expect(await tokenManager.isOperator(service.address)).to.be.true; - expect(await tokenManager.isFlowLimiter(wallet.address)).to.be.true; - expect(await tokenManager.isFlowLimiter(service.address)).to.be.true; - - const token = await getContractAt('InterchainToken', tokenAddress, wallet); - expect(await token.isMinter(wallet.address)).to.be.true; - expect(await token.isMinter(tokenManager.address)).to.be.true; - }); - - it('Should revert when registering an interchain token as a lock/unlock for a second time', async () => { - expect(await tokenManager.hasRole(wallet.address, OPERATOR_ROLE)).to.be.true; - - // Register the same token again - const revertData = keccak256(toUtf8Bytes('AlreadyDeployed()')).substring(0, 10); - await expectRevert( - (gasOptions) => - service.deployInterchainToken(salt, '', tokenName, tokenSymbol, tokenDecimals, wallet.address, 0, gasOptions), - service, - 'InterchainTokenDeploymentFailed', - [revertData], - ); - }); - it('Should revert when registering an interchain token when service is paused', async () => { await service.setPauseStatus(true).then((tx) => tx.wait); @@ -746,41 +699,6 @@ describe('Interchain Token Service', () => { await service.setPauseStatus(false).then((tx) => tx.wait); }); - - it('Should revert when registering an interchain token with empty token name', async () => { - expect(await tokenManager.hasRole(wallet.address, OPERATOR_ROLE)).to.be.true; - - await expectRevert( - (gasOptions) => service.deployInterchainToken(salt, '', '', tokenSymbol, tokenDecimals, wallet.address, 0, gasOptions), - service, - 'EmptyTokenName', - ); - }); - - it('Should revert when registering an interchain token with empty token symbol', async () => { - expect(await tokenManager.hasRole(wallet.address, OPERATOR_ROLE)).to.be.true; - - await expectRevert( - (gasOptions) => service.deployInterchainToken(salt, '', tokenName, '', tokenDecimals, wallet.address, 0, gasOptions), - service, - 'EmptyTokenSymbol', - ); - }); - - it('Should revert when deploying an interchain token on chain native to ITS hub', async () => { - await expect(service.setTrustedAddress(chainName, ITS_HUB_ROUTING_IDENTIFIER)) - .to.emit(service, 'TrustedAddressSet') - .withArgs(chainName, ITS_HUB_ROUTING_IDENTIFIER); - - await expectRevert( - (gasOptions) => - service.deployInterchainToken(salt, '', tokenName, tokenSymbol, tokenDecimals, wallet.address, 0, gasOptions), - service, - 'NotSupported', - ); - - await expect(service.removeTrustedAddress(chainName)).to.emit(service, 'TrustedAddressRemoved').withArgs(chainName); - }); }); describe('Deploy and Register remote Interchain Token', () => { From 0e7bb8bdc76109516c2ea4c5e1f0b52bdae25aac Mon Sep 17 00:00:00 2001 From: Foivos Date: Wed, 15 Jan 2025 18:30:54 +0200 Subject: [PATCH 7/7] prettier --- test/InterchainTokenService.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index 74bb275d..61c0643a 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -685,7 +685,6 @@ describe('Interchain Token Service', () => { const tokenSymbol = 'TN'; const tokenDecimals = 13; const salt = getRandomBytes32(); - let tokenManager; it('Should revert when registering an interchain token when service is paused', async () => { await service.setPauseStatus(true).then((tx) => tx.wait);