diff --git a/test/InterchainTokenFactory.js b/test/InterchainTokenFactory.js index b75e2c49..163f6df5 100644 --- a/test/InterchainTokenFactory.js +++ b/test/InterchainTokenFactory.js @@ -700,6 +700,23 @@ describe('InterchainTokenFactory', () => { ); }); + it('Should not be able to migrate a token deployed after this upgrade', async () => { + const salt = getRandomBytes32(); + const name = 'migrated token'; + const symbol = 'MT'; + const decimals = 53; + const tokenId = await tokenFactory.interchainTokenId(wallet.address, salt); + + await tokenFactory.deployInterchainToken(salt, name, symbol, decimals, 0, wallet.address).then((tx) => tx.wait); + const tokenAddress = await service.interchainTokenAddress(tokenId); + const token = await getContractAt('InterchainToken', tokenAddress, wallet); + + await expectRevert((gasOptions) => service.migrateInterchainToken(tokenId, { gasOptions }), token, 'MissingRole', [ + service.address, + MINTER_ROLE, + ]); + }); + describe('Custom Token Manager Deployment', () => { const tokenName = 'Token Name'; const tokenSymbol = 'TN'; @@ -761,6 +778,21 @@ describe('InterchainTokenFactory', () => { ); }); + it('Should revert when deploying a custom token when the service is paused', async () => { + const salt = getRandomBytes32(); + const tokenId = await tokenFactory.linkedTokenId(wallet.address, salt); + const deploySalt = await tokenFactory.linkedTokenDeploySalt(wallet.address, salt); + const tokenManagerAddress = await service.tokenManagerAddress(tokenId); + const gasValue = 1; + const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); + + await service.setPauseStatus(true).then((tx) => tx.wait); + + await expectRevert((gasOptions) => tokenFactory.registerCustomToken(salt, token.address, LOCK_UNLOCK, AddressZero, gasValue, { value: gasValue, ...gasOptions }), service, 'Pause'); + + await service.setPauseStatus(false).then((tx) => tx.wait); + }); + it('Should register a custom token with no operator', async () => { const salt = getRandomBytes32(); const tokenId = await tokenFactory.linkedTokenId(wallet.address, salt); diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index b9e76063..e2ed80cc 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -214,19 +214,18 @@ describe('Interchain Token Service', () => { return [token, tokenManager, tokenId]; }; - async function deployNewInterchainToken(service, tokenName, tokenSymbol, tokenDecimals, mintAmount = 0, skipApprove = false) { + async function deployNewInterchainToken(service, tokenName, tokenSymbol, tokenDecimals, minter = null, mintAmount = 0, skipApprove = false) { const salt = getRandomBytes32(); const tokenId = await service.interchainTokenId(wallet.address, salt); const sourceAddress = service.address; const tokenManagerAddress = await service.tokenManagerAddress(tokenId); - const minter = wallet.address; const operator = '0x'; const tokenAddress = await service.interchainTokenAddress(tokenId); - const params = defaultAbiCoder.encode(['bytes', 'address'], [minter, tokenAddress]); + const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, tokenAddress]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, tokenId, tokenName, tokenSymbol, tokenDecimals, minter, operator], + [MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, tokenId, tokenName, tokenSymbol, tokenDecimals, wallet.address, operator], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -245,6 +244,9 @@ describe('Interchain Token Service', () => { await token.mint(wallet.address, mintAmount).then((tx) => tx.wait); if (!skipApprove) await token.approve(service.address, mintAmount).then((tx) => tx.wait); } + if (minter) { + await token.transferMintership(minter).then((tx) => tx.wait); + } return [token, tokenManager, tokenId, salt]; } @@ -686,54 +688,6 @@ describe('Interchain Token Service', () => { const tokenSymbol = 'TN'; const tokenDecimals = 13; 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); @@ -1224,6 +1178,20 @@ describe('Interchain Token Service', () => { ); }); + it('Should revert on initiate an interchain token transfer to the ITS HUB', async () => { + const [, , tokenId] = await deployFunctions.lockUnlockFee( + service, + 'Test Token lockUnlockFee', + 'TT', + 12, + amount, + false, + 'free', + ); + + await expectRevert((gasOptions) => service.interchainTransfer(tokenId, ITS_HUB_CHAIN_NAME, destAddress, amount, '0x', gasValue, { value: gasValue, ...gasOptions }), service, 'UntrustedChain'); + }); + it('Should revert on initiate interchain token transfer when service is paused', async () => { await service.setPauseStatus(true).then((tx) => tx.wait); @@ -2957,13 +2925,13 @@ describe('Interchain Token Service', () => { }); }); - describe.only('Interchain Token Migration', () => { + describe('Interchain Token Migration', () => { it('Should migrate a token succesfully', async () => { const name = 'migrated token'; const symbol = 'MT'; const decimals = 53; - const [token, tokenManager, tokenId] = await deployFunctions.interchainToken(service, name, symbol, decimals); + const [token, tokenManager, tokenId] = await deployFunctions.interchainToken(service, name, symbol, decimals, service.address); await expect(service.migrateInterchainToken(tokenId)) .to.emit(token, 'RolesRemoved') @@ -2973,28 +2941,17 @@ describe('Interchain Token Service', () => { }); it('Should not be able to migrate a token twice', async () => { - const salt = getRandomBytes32(); const name = 'migrated token'; const symbol = 'MT'; const decimals = 53; - const tokenId = await service.interchainTokenId(wallet.address, salt); - const tokenManagerAddress = await service.tokenManagerAddress(tokenId); - - await interchainTokenDeployer - .deployInterchainToken(salt, tokenId, service.address, name, symbol, decimals) - .then((tx) => tx.wait); - const tokenAddress = await interchainTokenDeployer.deployedAddress(salt); - const token = await getContractAt('InterchainToken', tokenAddress, wallet); - - const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, tokenAddress]); - - await service.deployTokenManager(salt, '', MINT_BURN, params, 0).then((tx) => tx.wait); + + const [token, tokenManager, tokenId] = await deployFunctions.interchainToken(service, name, symbol, decimals, service.address); await expect(service.migrateInterchainToken(tokenId)) .to.emit(token, 'RolesRemoved') .withArgs(service.address, 1 << MINTER_ROLE) .to.emit(token, 'RolesAdded') - .withArgs(tokenManagerAddress, 1 << MINTER_ROLE); + .withArgs(tokenManager.address, 1 << MINTER_ROLE); await expectRevert((gasOptions) => service.migrateInterchainToken(tokenId, { gasOptions }), token, 'MissingRole', [ service.address, @@ -3002,22 +2959,15 @@ describe('Interchain Token Service', () => { ]); }); - it('Should not be able to migrate a token deployed after this upgrade', async () => { - const salt = getRandomBytes32(); + it('Should not be able to migrate a token as not the owner', async () => { const name = 'migrated token'; const symbol = 'MT'; const decimals = 53; - const tokenId = await service.interchainTokenId(wallet.address, salt); - await service.deployInterchainToken(salt, '', name, symbol, decimals, AddressZero, 0).then((tx) => tx.wait); - const tokenAddress = await service.interchainTokenAddress(tokenId); - const token = await getContractAt('InterchainToken', tokenAddress, wallet); + const [, , tokenId] = await deployFunctions.interchainToken(service, name, symbol, decimals, service.address); - await expectRevert((gasOptions) => service.migrateInterchainToken(tokenId, { gasOptions }), token, 'MissingRole', [ - service.address, - MINTER_ROLE, - ]); - }); + await expectRevert((gasOptions) => service.connect(otherWallet).migrateInterchainToken(tokenId, gasOptions), service, 'NotOwner'); + }) }); describe('Bytecode checks [ @skip-on-coverage ]', () => {