From ece8a092807044cf74761653251e19c8836c82b3 Mon Sep 17 00:00:00 2001 From: Foivos Date: Thu, 7 Mar 2024 15:26:20 +0200 Subject: [PATCH 1/4] added a check to prevent zero amount transfers --- contracts/InterchainTokenService.sol | 1 + contracts/interfaces/IInterchainTokenService.sol | 1 + 2 files changed, 2 insertions(+) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index a0e41ac5..d03be982 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -1048,6 +1048,7 @@ contract InterchainTokenService is string memory symbol, uint256 gasValue ) internal { + if (amount == 0) revert ZeroAmount(); // slither-disable-next-line reentrancy-events emit InterchainTransfer( tokenId, diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 6913b827..d069871e 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -47,6 +47,7 @@ interface IInterchainTokenService is error TokenHandlerFailed(bytes data); error EmptyData(); error PostDeployFailed(bytes data); + error ZeroAmount(); event InterchainTransfer( bytes32 indexed tokenId, From 81d4e145bfcebb053f509fc3834865c6426f1588 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 22 Mar 2024 04:41:06 -0400 Subject: [PATCH 2/4] Update contracts/InterchainTokenService.sol --- contracts/InterchainTokenService.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index d03be982..ec42ddf8 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -1049,6 +1049,7 @@ contract InterchainTokenService is uint256 gasValue ) internal { if (amount == 0) revert ZeroAmount(); + // slither-disable-next-line reentrancy-events emit InterchainTransfer( tokenId, From 6806b5c77b400209e27574065a79fd96086e83d3 Mon Sep 17 00:00:00 2001 From: Foivos Date: Wed, 27 Mar 2024 19:10:54 +0200 Subject: [PATCH 3/4] added test coverage --- test/InterchainTokenService.js | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index d99cbddd..1c477082 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -1258,6 +1258,18 @@ describe('Interchain Token Service', () => { ); }); + it(`Should revert on initiate interchain token transfer with zero amount`, async () => { + await expectRevert( + (gasOptions) => + service.interchainTransfer(tokenId, destinationChain, destAddress, 0, '0x', gasValue, { + ...gasOptions, + value: gasValue, + }), + service, + 'ZeroAmount', + ); + }); + it(`Should revert on initiate interchain token transfer when service is paused`, async () => { await service.setPauseStatus(true).then((tx) => tx.wait); @@ -1638,6 +1650,16 @@ describe('Interchain Token Service', () => { .withArgs(tokenId, sourceAddress, destinationChain, destAddress, sendAmount, HashZero); }); + it(`Should revert on callContractWithInterchainToken function on the service if amount is 0`, async () => { + const [, , tokenId] = await deployFunctions.lockUnlock(`Test Token`, 'TT', 12, amount); + + await expectRevert( + (gasOptions) => service.callContractWithInterchainToken(tokenId, destinationChain, destAddress, 0, data, 0, gasOptions), + service, + 'ZeroAmount', + ); + }); + for (const type of ['lockUnlock', 'lockUnlockFee']) { it(`Should be able to initiate an interchain token transfer via the interchainTransfer function on the service when the service is approved as well [${type}]`, async () => { const [token, tokenManager, tokenId] = await deployFunctions[type](`Test Token ${type}`, 'TT', 12, amount); @@ -2030,6 +2052,24 @@ describe('Interchain Token Service', () => { .withArgs(tokenId, sender.address, destinationChain, destAddress, sendAmount, HashZero); }); + it(`Should revert using interchainTransferFrom with zero amount`, async () => { + const sender = wallet; + const spender = otherWallet; + await token.approve(spender.address, MaxUint256).then((tx) => tx.wait); + + await expectRevert( + (gasOptions) => + token + .connect(spender) + .interchainTransferFrom(sender.address, destinationChain, destAddress, 0, metadata, { + value: gasValue, + ...gasOptions, + }), + service, + 'ZeroAmount', + ); + }); + it(`Should be able to initiate an interchain token transfer via interchainTransfer & interchainTransferFrom [gateway]`, async () => { const symbol = 'TT2'; [token, tokenManager, tokenId] = await deployFunctions.gateway(`Test Token gateway`, symbol, 12, amount * 3, true); From 8f48348a90cb8cc7885bd49376e142c2dd8fb9e0 Mon Sep 17 00:00:00 2001 From: Foivos Date: Wed, 27 Mar 2024 21:32:40 +0200 Subject: [PATCH 4/4] prettier --- test/InterchainTokenService.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index 1c477082..868b7f0e 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -2059,12 +2059,10 @@ describe('Interchain Token Service', () => { await expectRevert( (gasOptions) => - token - .connect(spender) - .interchainTransferFrom(sender.address, destinationChain, destAddress, 0, metadata, { - value: gasValue, - ...gasOptions, - }), + token.connect(spender).interchainTransferFrom(sender.address, destinationChain, destAddress, 0, metadata, { + value: gasValue, + ...gasOptions, + }), service, 'ZeroAmount', );