Skip to content

Commit

Permalink
feat: added a check to prevent zero amount transfers (#252)
Browse files Browse the repository at this point in the history
* added a check to prevent zero amount transfers

* Update contracts/InterchainTokenService.sol

* added test coverage

* prettier

---------

Co-authored-by: Milap Sheth <[email protected]>
  • Loading branch information
Foivos and milapsheth authored Mar 27, 2024
1 parent aede779 commit 672b48d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
2 changes: 2 additions & 0 deletions contracts/InterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,8 @@ contract InterchainTokenService is
string memory symbol,
uint256 gasValue
) internal {
if (amount == 0) revert ZeroAmount();

// slither-disable-next-line reentrancy-events
emit InterchainTransfer(
tokenId,
Expand Down
1 change: 1 addition & 0 deletions contracts/interfaces/IInterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface IInterchainTokenService is
error TokenHandlerFailed(bytes data);
error EmptyData();
error PostDeployFailed(bytes data);
error ZeroAmount();

event InterchainTransfer(
bytes32 indexed tokenId,
Expand Down
38 changes: 38 additions & 0 deletions test/InterchainTokenService.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -2030,6 +2052,22 @@ 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);
Expand Down

0 comments on commit 672b48d

Please sign in to comment.