Skip to content

Commit

Permalink
Merge branch 'main' into fix/remove-unnecessary-payable
Browse files Browse the repository at this point in the history
  • Loading branch information
ahramy authored Nov 11, 2024
2 parents 83425f0 + cd3af09 commit 0774feb
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
10 changes: 10 additions & 0 deletions contracts/InterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ contract InterchainTokenService is
bytes calldata params,
uint256 gasValue
) external payable whenNotPaused returns (bytes32 tokenId) {
if (bytes(params).length == 0) revert EmptyParams();

// Custom token managers can't be deployed with native interchain token type, which is reserved for interchain tokens
if (tokenManagerType == TokenManagerType.NATIVE_INTERCHAIN_TOKEN) revert CannotDeploy(tokenManagerType);

Expand Down Expand Up @@ -516,6 +518,7 @@ contract InterchainTokenService is
uint256 gasValue
) external payable whenNotPaused {
if (data.length == 0) revert EmptyData();

amount = _takeToken(tokenId, msg.sender, amount, false);

_transmitInterchainTransfer(
Expand Down Expand Up @@ -908,6 +911,9 @@ contract InterchainTokenService is
string calldata destinationChain,
uint256 gasValue
) internal {
if (bytes(name).length == 0) revert EmptyTokenName();
if (bytes(symbol).length == 0) revert EmptyTokenSymbol();

// slither-disable-next-line unused-return
deployedTokenManager(tokenId);

Expand Down Expand Up @@ -969,6 +975,9 @@ contract InterchainTokenService is
string memory symbol,
uint8 decimals
) internal returns (address tokenAddress) {
if (bytes(name).length == 0) revert EmptyTokenName();
if (bytes(symbol).length == 0) revert EmptyTokenSymbol();

bytes32 salt = _getInterchainTokenSalt(tokenId);

address minter;
Expand Down Expand Up @@ -1030,6 +1039,7 @@ contract InterchainTokenService is
bytes memory data,
uint256 gasValue
) internal {
if (destinationAddress.length == 0) revert EmptyDestinationAddress();
if (amount == 0) revert ZeroAmount();

// slither-disable-next-line reentrancy-events
Expand Down
4 changes: 4 additions & 0 deletions contracts/interfaces/IInterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ interface IInterchainTokenService is
error CannotDeployRemotelyToSelf();
error InvalidPayload();
error GatewayCallFailed(bytes data);
error EmptyTokenName();
error EmptyTokenSymbol();
error EmptyParams();
error EmptyDestinationAddress();

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

describe('Deploy and Register remote Interchain Token', () => {
Expand Down Expand Up @@ -728,6 +748,30 @@ describe('Interchain Token Service', () => {
);
});

it('Should revert on remote interchain token deployment with invalid token name', async () => {
await expectRevert(
(gasOptions) =>
service.deployInterchainToken(salt, destinationChain, '', tokenSymbol, tokenDecimals, minter, gasValue, {
...gasOptions,
value: gasValue,
}),
service,
'EmptyTokenName',
);
});

it('Should revert on remote interchain token deployment with invalid token symbol', async () => {
await expectRevert(
(gasOptions) =>
service.deployInterchainToken(salt, destinationChain, tokenName, '', tokenDecimals, minter, gasValue, {
...gasOptions,
value: gasValue,
}),
service,
'EmptyTokenSymbol',
);
});

it('Should revert on remote interchain token deployment if paused', async () => {
await service.setPauseStatus(true).then((tx) => tx.wait);

Expand Down Expand Up @@ -820,6 +864,14 @@ describe('Interchain Token Service', () => {
await expectRevert((gasOptions) => service.deployTokenManager(salt, '', 6, params, 0, gasOptions));
});

it('Should revert on deploying a local token manager with invalid params', async () => {
await expectRevert(
(gasOptions) => service.deployTokenManager(salt, '', NATIVE_INTERCHAIN_TOKEN, '0x', 0, gasOptions),
service,
'EmptyParams',
);
});

it('Should revert on deploying a local token manager with interchain token manager type', async () => {
const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, token.address]);

Expand Down Expand Up @@ -1271,6 +1323,18 @@ describe('Interchain Token Service', () => {
);
});

it('Should revert on initiate interchain token transfer with invalid destination address', async () => {
await expectRevert(
(gasOptions) =>
service.interchainTransfer(tokenId, destinationChain, '0x', amount, '0x', gasValue, {
...gasOptions,
value: gasValue,
}),
service,
'EmptyDestinationAddress',
);
});

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 @@ -1299,6 +1363,18 @@ describe('Interchain Token Service', () => {
await service.setPauseStatus(false).then((tx) => tx.wait);
});

it('Should revert on transmit send token when destination address is zero address', async () => {
await expectRevert(
(gasOptions) =>
service.transmitInterchainTransfer(tokenId, wallet.address, destinationChain, '0x', amount, '0x', {
...gasOptions,
value: gasValue,
}),
service,
'TakeTokenFailed',
);
});

it('Should revert on transmit send token when not called by interchain token', async () => {
const errorSignatureHash = id('NotToken(address,address)');
const selector = errorSignatureHash.substring(0, 10);
Expand Down Expand Up @@ -1638,6 +1714,16 @@ describe('Interchain Token Service', () => {
);
});

it('Should revert on callContractWithInterchainToken function on the service with invalid destination address', async () => {
const [, , tokenId] = await deployFunctions.lockUnlock(service, 'Test Token', 'TT', 12, amount);

await expectRevert(
(gasOptions) => service.callContractWithInterchainToken(tokenId, destinationChain, '0x', amount, data, 0, gasOptions),
service,
'EmptyDestinationAddress',
);
});

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](service, `Test Token ${type}`, 'TT', 12, amount);
Expand Down

0 comments on commit 0774feb

Please sign in to comment.