Skip to content

Commit 2f3033c

Browse files
authored
Merge branch 'main' into refactor/minter
2 parents a00b9a4 + 04a7664 commit 2f3033c

File tree

3 files changed

+55
-26
lines changed

3 files changed

+55
-26
lines changed

contracts/InterchainTokenService.sol

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ contract InterchainTokenService is
7373
/**
7474
* @dev The message types that are sent between InterchainTokenService on different chains.
7575
*/
76+
7677
uint256 private constant MESSAGE_TYPE_INTERCHAIN_TRANSFER = 0;
7778
uint256 private constant MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN = 1;
7879
uint256 private constant MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER = 2;
@@ -81,12 +82,18 @@ contract InterchainTokenService is
8182
* @dev Tokens and token managers deployed via the Token Factory contract use a special deployer address.
8283
* This removes the dependency on the address the token factory was deployed too to be able to derive the same tokenId.
8384
*/
84-
address private constant TOKEN_FACTORY_DEPLOYER = address(0);
85+
address internal constant TOKEN_FACTORY_DEPLOYER = address(0);
8586

8687
/**
8788
* @dev Latest version of metadata that's supported.
8889
*/
89-
uint32 private constant LATEST_METADATA_VERSION = 0;
90+
91+
enum MetadataVersion {
92+
CONTRACT_CALL,
93+
EXPRESS_CALL
94+
}
95+
96+
uint32 internal constant LATEST_METADATA_VERSION = 1;
9097

9198
/**
9299
* @notice Constructor for the Interchain Token Service.
@@ -453,7 +460,7 @@ contract InterchainTokenService is
453460
) external payable whenNotPaused {
454461
(amount, ) = _takeToken(tokenId, msg.sender, amount);
455462

456-
(uint32 metadataVersion, bytes memory data) = _decodeMetadata(metadata);
463+
(MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata);
457464

458465
_transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadataVersion, data);
459466
}
@@ -475,12 +482,12 @@ contract InterchainTokenService is
475482
) external payable whenNotPaused {
476483
(amount, ) = _takeToken(tokenId, msg.sender, amount);
477484

478-
_transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, LATEST_METADATA_VERSION, data);
485+
_transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, MetadataVersion.CONTRACT_CALL, data);
479486
}
480487

481-
/*********************\
488+
/******************\
482489
TOKEN ONLY FUNCTIONS
483-
\*********************/
490+
\******************/
484491

485492
/**
486493
* @notice Transmit an interchain transfer for the given tokenId.
@@ -507,7 +514,7 @@ contract InterchainTokenService is
507514

508515
if (sender != tokenAddress) revert NotToken(sender, tokenAddress);
509516

510-
(uint32 metadataVersion, bytes memory data) = _decodeMetadata(metadata);
517+
(MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata);
511518

512519
_transmitInterchainTransfer(tokenId, sourceAddress, destinationChain, destinationAddress, amount, metadataVersion, data);
513520
}
@@ -750,18 +757,33 @@ contract InterchainTokenService is
750757
* @param payload The data payload for the transaction.
751758
* @param gasValue The amount of gas to be paid for the transaction.
752759
*/
753-
function _callContract(string calldata destinationChain, bytes memory payload, uint256 gasValue) internal {
760+
function _callContract(
761+
string calldata destinationChain,
762+
bytes memory payload,
763+
MetadataVersion metadataVersion,
764+
uint256 gasValue
765+
) internal {
754766
string memory destinationAddress = trustedAddress(destinationChain);
755767
if (bytes(destinationAddress).length == 0) revert UntrustedChain();
756768

757769
if (gasValue > 0) {
758-
gasService.payNativeGasForContractCall{ value: gasValue }(
759-
address(this),
760-
destinationChain,
761-
destinationAddress,
762-
payload, // solhint-disable-next-line avoid-tx-origin
763-
tx.origin
764-
);
770+
if (metadataVersion == MetadataVersion.CONTRACT_CALL) {
771+
gasService.payNativeGasForContractCall{ value: gasValue }(
772+
address(this),
773+
destinationChain,
774+
destinationAddress,
775+
payload, // solhint-disable-next-line avoid-tx-origin
776+
tx.origin
777+
);
778+
} else if (metadataVersion == MetadataVersion.EXPRESS_CALL) {
779+
gasService.payNativeGasForExpressCall{ value: gasValue }(
780+
address(this),
781+
destinationChain,
782+
destinationAddress,
783+
payload, // solhint-disable-next-line avoid-tx-origin
784+
tx.origin
785+
);
786+
}
765787
}
766788

767789
gateway.callContract(destinationChain, destinationAddress, payload);
@@ -789,7 +811,7 @@ contract InterchainTokenService is
789811

790812
bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, tokenManagerType, params);
791813

792-
_callContract(destinationChain, payload, gasValue);
814+
_callContract(destinationChain, payload, MetadataVersion.CONTRACT_CALL, gasValue);
793815
}
794816

795817
/**
@@ -819,7 +841,7 @@ contract InterchainTokenService is
819841

820842
bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, tokenId, name, symbol, decimals, minter);
821843

822-
_callContract(destinationChain, payload, gasValue);
844+
_callContract(destinationChain, payload, MetadataVersion.CONTRACT_CALL, gasValue);
823845
}
824846

825847
/**
@@ -898,10 +920,13 @@ contract InterchainTokenService is
898920
* @return version The version number extracted from the metadata.
899921
* @return data The data bytes extracted from the metadata.
900922
*/
901-
function _decodeMetadata(bytes calldata metadata) internal pure returns (uint32 version, bytes memory data) {
902-
if (metadata.length < 4) return (LATEST_METADATA_VERSION, data);
923+
function _decodeMetadata(bytes calldata metadata) internal pure returns (MetadataVersion version, bytes memory data) {
924+
if (metadata.length < 4) return (MetadataVersion.CONTRACT_CALL, data);
925+
926+
uint32 versionUint = uint32(bytes4(metadata[:4]));
927+
if (versionUint > LATEST_METADATA_VERSION) revert InvalidMetadataVersion(versionUint);
903928

904-
version = uint32(bytes4(metadata[:4]));
929+
version = MetadataVersion(versionUint);
905930

906931
if (metadata.length == 4) return (version, data);
907932

@@ -924,11 +949,9 @@ contract InterchainTokenService is
924949
string calldata destinationChain,
925950
bytes memory destinationAddress,
926951
uint256 amount,
927-
uint32 metadataVersion,
952+
MetadataVersion metadataVersion,
928953
bytes memory data
929954
) internal {
930-
if (metadataVersion > LATEST_METADATA_VERSION) revert InvalidMetadataVersion(metadataVersion);
931-
932955
// slither-disable-next-line reentrancy-events
933956
emit InterchainTransfer(
934957
tokenId,
@@ -948,7 +971,7 @@ contract InterchainTokenService is
948971
data
949972
);
950973

951-
_callContract(destinationChain, payload, msg.value);
974+
_callContract(destinationChain, payload, metadataVersion, msg.value);
952975
}
953976

954977
/**

contracts/test/TestInterchainTokenService.sol

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ pragma solidity ^0.8.0;
55
import { InterchainTokenService } from '../InterchainTokenService.sol';
66

77
contract TestInterchainTokenService is InterchainTokenService {
8+
error LatestMetadataVersionMismatch(uint32 const, uint32 calculated);
9+
810
constructor(
911
address tokenManagerDeployer_,
1012
address interchainTokenDeployer_,
@@ -25,7 +27,10 @@ contract TestInterchainTokenService is InterchainTokenService {
2527
tokenManager_,
2628
tokenHandler_
2729
)
28-
{}
30+
{
31+
if (LATEST_METADATA_VERSION != uint32(type(MetadataVersion).max))
32+
revert LatestMetadataVersionMismatch(LATEST_METADATA_VERSION, uint32(type(MetadataVersion).max));
33+
}
2934

3035
function setupTest(bytes calldata params) external {
3136
_setup(params);

test/InterchainTokenService.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,12 +1644,13 @@ describe('Interchain Token Service', () => {
16441644
it(`Should revert on interchainTransfer function with invalid metadata version`, async () => {
16451645
const [, , tokenId] = await deployFunctions.lockUnlock(`Test Token lockUnlock`, 'TT', 12, amount);
16461646

1647-
const metadata = '0x00000001';
1647+
const metadata = '0x00000002';
16481648

16491649
await expectRevert(
16501650
(gasOptions) => service.interchainTransfer(tokenId, destinationChain, destAddress, amount, metadata, gasOptions),
16511651
service,
16521652
'InvalidMetadataVersion',
1653+
[Number(metadata)],
16531654
);
16541655
});
16551656
});

0 commit comments

Comments
 (0)