From 914ef81abfc8a30719eaa75ea4bbe4f2884e9e13 Mon Sep 17 00:00:00 2001 From: ahramy Date: Wed, 21 Aug 2024 11:05:11 -0700 Subject: [PATCH 01/25] implement AxelarGMPExecutableWithToken --- contracts/InterchainTokenFactory.sol | 9 ++- contracts/InterchainTokenService.sol | 70 +++++++------------ .../interfaces/IInterchainTokenService.sol | 6 +- 3 files changed, 35 insertions(+), 50 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index 2c042e58..417c407f 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol'; import { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; -import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol'; +import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; import { IInterchainTokenService } from './interfaces/IInterchainTokenService.sol'; import { IInterchainTokenFactory } from './interfaces/IInterchainTokenFactory.sol'; @@ -22,7 +22,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M IInterchainTokenService public immutable interchainTokenService; bytes32 public immutable chainNameHash; - IAxelarGateway public immutable gateway; + IAxelarGMPGatewayWithToken public immutable gateway; bytes32 private constant CONTRACT_ID = keccak256('interchain-token-factory'); bytes32 internal constant PREFIX_CANONICAL_TOKEN_SALT = keccak256('canonical-token-salt'); @@ -40,7 +40,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M interchainTokenService = IInterchainTokenService(interchainTokenService_); chainNameHash = interchainTokenService.chainNameHash(); - gateway = interchainTokenService.gateway(); + gateway = interchainTokenService.getGatewayAddress(); } /** @@ -51,6 +51,9 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M return CONTRACT_ID; } + function _setup(bytes calldata params) internal override { + } + /** * @notice Calculates the salt for an interchain token. * @param chainNameHash_ The hash of the chain name. diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index b997e98e..c75b8c8a 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -4,14 +4,15 @@ pragma solidity ^0.8.0; import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; -import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol'; -import { ExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol'; +import { AxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutable.sol'; +import { AxelarGMPExecutableWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutableWithToken.sol'; +import { IAxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPExecutable.sol'; +import { GMPExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/GMPExpressExecutorTracker.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol'; import { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol'; import { Pausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Pausable.sol'; import { InterchainAddressTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/InterchainAddressTracker.sol'; - import { IInterchainTokenService } from './interfaces/IInterchainTokenService.sol'; import { ITokenHandler } from './interfaces/ITokenHandler.sol'; import { ITokenManagerDeployer } from './interfaces/ITokenManagerDeployer.sol'; @@ -23,6 +24,7 @@ import { IGatewayCaller } from './interfaces/IGatewayCaller.sol'; import { Create3AddressFixed } from './utils/Create3AddressFixed.sol'; import { Operator } from './utils/Operator.sol'; +import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; /** * @title The Interchain Token Service @@ -37,14 +39,14 @@ contract InterchainTokenService is Pausable, Multicall, Create3AddressFixed, - ExpressExecutorTracker, InterchainAddressTracker, + AxelarGMPExecutableWithToken, + GMPExpressExecutorTracker, IInterchainTokenService { using AddressBytes for bytes; using AddressBytes for address; - IAxelarGateway public immutable gateway; IAxelarGasService public immutable gasService; address public immutable interchainTokenFactory; bytes32 public immutable chainNameHash; @@ -124,7 +126,7 @@ contract InterchainTokenService is address tokenManagerImplementation_, address tokenHandler_, address gatewayCaller_ - ) { + ) AxelarGMPExecutableWithToken(gateway_) { if ( gasService_ == address(0) || tokenManagerDeployer_ == address(0) || @@ -136,7 +138,6 @@ contract InterchainTokenService is gatewayCaller_ == address(0) ) revert ZeroAddress(); - gateway = IAxelarGateway(gateway_); gasService = IAxelarGasService(gasService_); tokenManagerDeployer = tokenManagerDeployer_; interchainTokenDeployer = interchainTokenDeployer_; @@ -377,13 +378,13 @@ contract InterchainTokenService is string calldata sourceChain, string calldata sourceAddress, bytes calldata payload - ) public payable whenNotPaused { + ) public payable override whenNotPaused { uint256 messageType = abi.decode(payload, (uint256)); if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) { revert InvalidExpressMessageType(messageType); } - if (gateway.isCommandExecuted(commandId)) revert AlreadyExecuted(); + if (IAxelarGMPGatewayWithToken(gatewayAddress).isCommandExecuted(commandId)) revert AlreadyExecuted(); address expressExecutor = msg.sender; bytes32 payloadHash = keccak256(payload); @@ -622,24 +623,8 @@ contract InterchainTokenService is } } - /** - * @notice Executes operations based on the payload and selector. - * @param commandId The unique message id. - * @param sourceChain The chain where the transaction originates from. - * @param sourceAddress The address of the remote ITS where the transaction originates from. - * @param payload The encoded data payload for the transaction. - */ - function execute( - bytes32 commandId, - string calldata sourceChain, - string calldata sourceAddress, - bytes calldata payload - ) external onlyRemoteService(sourceChain, sourceAddress) whenNotPaused { - bytes32 payloadHash = keccak256(payload); - - if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); - - _execute(commandId, sourceChain, sourceAddress, payload, payloadHash); + function getGatewayAddress() external view returns (IAxelarGMPGatewayWithToken) { + return IAxelarGMPGatewayWithToken(gatewayAddress); } /** @@ -686,17 +671,6 @@ contract InterchainTokenService is expressExecute(commandId, sourceChain, sourceAddress, payload); } - function executeWithToken( - bytes32 commandId, - string calldata sourceChain, - string calldata sourceAddress, - bytes calldata payload, - string calldata tokenSymbol, - uint256 amount - ) external onlyRemoteService(sourceChain, sourceAddress) whenNotPaused { - _executeWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount); - } - /** * @notice Check that the tokenId from the payload is a token that is registered in the gateway with the proper tokenSymbol, with the right amount from the payload. * Also check that the amount in the payload matches the one for the call. @@ -707,7 +681,7 @@ contract InterchainTokenService is function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - if (validTokenAddress(tokenId) != gateway.tokenAddresses(tokenSymbol) || amount != amountInPayload) + if (validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(gatewayAddress).tokenAddresses(tokenSymbol) || amount != amountInPayload) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } @@ -871,6 +845,16 @@ contract InterchainTokenService is if (!success) revert GatewayCallFailed(returnData); } + function callContractWithToken( + string calldata destinationChain, + string calldata contractAddress, + bytes calldata payload, + string calldata symbol, + uint256 amount + ) external override { + // do nothing ? + } + /** * @dev Get the params for the cross-chain message, taking routing via ITS Hub into account. */ @@ -903,7 +887,7 @@ contract InterchainTokenService is string calldata sourceAddress, bytes memory payload, bytes32 payloadHash - ) internal { + ) internal override whenNotPaused { uint256 messageType; string memory originalSourceChain; (messageType, originalSourceChain, payload) = _getExecuteParams(sourceChain, payload); @@ -927,12 +911,8 @@ contract InterchainTokenService is bytes memory payload, string calldata tokenSymbol, uint256 amount - ) internal { + ) internal override whenNotPaused { bytes32 payloadHash = keccak256(payload); - - if (!gateway.validateContractCallAndMint(commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount)) - revert NotApprovedByGateway(); - uint256 messageType; string memory originalSourceChain; (messageType, originalSourceChain, payload) = _getExecuteParams(sourceChain, payload); diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 150e0fba..98b9cad0 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.0; -import { IAxelarValuedExpressExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarValuedExpressExecutable.sol'; import { IMulticall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol'; import { IPausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IPausable.sol'; import { IUpgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol'; @@ -13,6 +12,8 @@ import { ITokenManagerImplementation } from './ITokenManagerImplementation.sol'; import { IOperator } from './IOperator.sol'; import { IAddressTracker } from './IAddressTracker.sol'; +import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; + /** * @title IInterchainTokenService Interface * @notice Interface for the Interchain Token Service @@ -21,7 +22,6 @@ interface IInterchainTokenService is ITransmitInterchainToken, ITokenManagerType, ITokenManagerImplementation, - IAxelarValuedExpressExecutable, IOperator, IPausable, IMulticall, @@ -94,6 +94,8 @@ interface IInterchainTokenService is ); event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); + function getGatewayAddress() external view returns (IAxelarGMPGatewayWithToken); + /** * @notice Returns the address of the token manager deployer contract. * @return tokenManagerDeployerAddress The address of the token manager deployer contract. From 7b8193de5ea6e84844693daa2e3c7cd1ebefe16f Mon Sep 17 00:00:00 2001 From: ahramy Date: Wed, 21 Aug 2024 23:52:01 -0700 Subject: [PATCH 02/25] implement AxelarGMPExecutableWithToken --- contracts/InterchainTokenFactory.sol | 3 +-- contracts/InterchainTokenService.sol | 32 ++++++++++++++++------------ contracts/utils/GatewayCaller.sol | 6 +++--- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index 417c407f..ff904370 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -51,8 +51,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M return CONTRACT_ID; } - function _setup(bytes calldata params) internal override { - } + function _setup(bytes calldata params) internal override {} /** * @notice Calculates the salt for an interchain token. diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index c75b8c8a..6e896547 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -7,7 +7,7 @@ import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contr import { AxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutable.sol'; import { AxelarGMPExecutableWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutableWithToken.sol'; import { IAxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPExecutable.sol'; -import { GMPExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/GMPExpressExecutorTracker.sol'; +import { ExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol'; import { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol'; @@ -40,8 +40,8 @@ contract InterchainTokenService is Multicall, Create3AddressFixed, InterchainAddressTracker, + ExpressExecutorTracker, AxelarGMPExecutableWithToken, - GMPExpressExecutorTracker, IInterchainTokenService { using AddressBytes for bytes; @@ -681,8 +681,10 @@ contract InterchainTokenService is function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - if (validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(gatewayAddress).tokenAddresses(tokenSymbol) || amount != amountInPayload) - revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); + if ( + validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(gatewayAddress).tokenAddresses(tokenSymbol) || + amount != amountInPayload + ) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } /** @@ -885,20 +887,21 @@ contract InterchainTokenService is bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, - bytes memory payload, - bytes32 payloadHash + bytes calldata payload ) internal override whenNotPaused { + bytes32 payloadHash = keccak256(payload); uint256 messageType; string memory originalSourceChain; - (messageType, originalSourceChain, payload) = _getExecuteParams(sourceChain, payload); + bytes memory originalPayload; + (messageType, originalSourceChain, originalPayload) = _getExecuteParams(sourceChain, payload); if (messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER) { address expressExecutor = _getExpressExecutorAndEmitEvent(commandId, sourceChain, sourceAddress, payloadHash); - _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, payload); + _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, originalPayload); } else if (messageType == MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER) { - _processDeployTokenManagerPayload(payload); + _processDeployTokenManagerPayload(originalPayload); } else if (messageType == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN) { - _processDeployInterchainTokenPayload(payload); + _processDeployInterchainTokenPayload(originalPayload); } else { revert InvalidMessageType(messageType); } @@ -908,25 +911,26 @@ contract InterchainTokenService is bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, - bytes memory payload, + bytes calldata payload, string calldata tokenSymbol, uint256 amount ) internal override whenNotPaused { bytes32 payloadHash = keccak256(payload); uint256 messageType; string memory originalSourceChain; - (messageType, originalSourceChain, payload) = _getExecuteParams(sourceChain, payload); + bytes memory originalPayload; + (messageType, originalSourceChain, originalPayload) = _getExecuteParams(sourceChain, payload); if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) { revert InvalidMessageType(messageType); } - _checkPayloadAgainstGatewayData(payload, tokenSymbol, amount); + _checkPayloadAgainstGatewayData(originalPayload, tokenSymbol, amount); // slither-disable-next-line reentrancy-events address expressExecutor = _getExpressExecutorAndEmitEvent(commandId, sourceChain, sourceAddress, payloadHash); - _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, payload); + _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, originalPayload); } function _getMessageType(bytes memory payload) internal pure returns (uint256 messageType) { diff --git a/contracts/utils/GatewayCaller.sol b/contracts/utils/GatewayCaller.sol index f739facd..2a8bc40f 100644 --- a/contracts/utils/GatewayCaller.sol +++ b/contracts/utils/GatewayCaller.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; -import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol'; +import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; import { IGatewayCaller } from '../interfaces/IGatewayCaller.sol'; /** @@ -11,7 +11,7 @@ import { IGatewayCaller } from '../interfaces/IGatewayCaller.sol'; * @dev This contract is used to handle cross-chain ITS calls via the Axelar gateway. */ contract GatewayCaller is IGatewayCaller { - IAxelarGateway public immutable gateway; + IAxelarGMPGatewayWithToken public immutable gateway; IAxelarGasService public immutable gasService; /** @@ -20,7 +20,7 @@ contract GatewayCaller is IGatewayCaller { * @param gasService_ The address of the AxelarGasService contract */ constructor(address gateway_, address gasService_) { - gateway = IAxelarGateway(gateway_); + gateway = IAxelarGMPGatewayWithToken(gateway_); gasService = IAxelarGasService(gasService_); } From 3aa1852cbaff5bafb019e8762edaeb614119124b Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 22 Aug 2024 00:41:21 -0700 Subject: [PATCH 03/25] removed callContractWithToken --- contracts/InterchainTokenService.sol | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 6e896547..7549e0f5 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -847,16 +847,6 @@ contract InterchainTokenService is if (!success) revert GatewayCallFailed(returnData); } - function callContractWithToken( - string calldata destinationChain, - string calldata contractAddress, - bytes calldata payload, - string calldata symbol, - uint256 amount - ) external override { - // do nothing ? - } - /** * @dev Get the params for the cross-chain message, taking routing via ITS Hub into account. */ From de54ecd523d78166471ce9bd0ef43350d348cfb5 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 22 Aug 2024 00:44:17 -0700 Subject: [PATCH 04/25] removed unused imports --- contracts/InterchainTokenService.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 7549e0f5..32aeb3df 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -4,9 +4,7 @@ pragma solidity ^0.8.0; import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; -import { AxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutable.sol'; import { AxelarGMPExecutableWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutableWithToken.sol'; -import { IAxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPExecutable.sol'; import { ExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol'; From ea2db98d6820e4010775613ca169887a4853aac0 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 22 Aug 2024 00:55:44 -0700 Subject: [PATCH 05/25] updated --- contracts/InterchainTokenFactory.sol | 2 +- contracts/InterchainTokenService.sol | 4 ---- contracts/interfaces/IInterchainTokenService.sol | 4 ++-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index ff904370..3fceb215 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -40,7 +40,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M interchainTokenService = IInterchainTokenService(interchainTokenService_); chainNameHash = interchainTokenService.chainNameHash(); - gateway = interchainTokenService.getGatewayAddress(); + gateway = interchainTokenService.gateway(); } /** diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 32aeb3df..51f92d9f 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -621,10 +621,6 @@ contract InterchainTokenService is } } - function getGatewayAddress() external view returns (IAxelarGMPGatewayWithToken) { - return IAxelarGMPGatewayWithToken(gatewayAddress); - } - /** * @notice Returns the amount of token that this call is worth. * @dev If `tokenAddress` is `0`, then value is in terms of the native token, otherwise it's in terms of the token address. diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 98b9cad0..f6d7d57b 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; +import { IAxelarValuedExpressExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarValuedExpressExecutable.sol'; import { IMulticall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol'; import { IPausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IPausable.sol'; import { IUpgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol'; @@ -22,6 +23,7 @@ interface IInterchainTokenService is ITransmitInterchainToken, ITokenManagerType, ITokenManagerImplementation, + IAxelarValuedExpressExecutable, IOperator, IPausable, IMulticall, @@ -94,8 +96,6 @@ interface IInterchainTokenService is ); event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); - function getGatewayAddress() external view returns (IAxelarGMPGatewayWithToken); - /** * @notice Returns the address of the token manager deployer contract. * @return tokenManagerDeployerAddress The address of the token manager deployer contract. From d8e00918d491a4402e40da99d941891e18f83495 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 22 Aug 2024 00:58:13 -0700 Subject: [PATCH 06/25] updated --- contracts/InterchainTokenService.sol | 2 +- contracts/interfaces/IInterchainTokenService.sol | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 51f92d9f..cb517951 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -37,8 +37,8 @@ contract InterchainTokenService is Pausable, Multicall, Create3AddressFixed, - InterchainAddressTracker, ExpressExecutorTracker, + InterchainAddressTracker, AxelarGMPExecutableWithToken, IInterchainTokenService { diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index f6d7d57b..150e0fba 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -13,8 +13,6 @@ import { ITokenManagerImplementation } from './ITokenManagerImplementation.sol'; import { IOperator } from './IOperator.sol'; import { IAddressTracker } from './IAddressTracker.sol'; -import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; - /** * @title IInterchainTokenService Interface * @notice Interface for the Interchain Token Service From 3f9d043f5c1b4608dd45a36ee63c915777645045 Mon Sep 17 00:00:00 2001 From: ahramy Date: Fri, 23 Aug 2024 21:37:04 -0700 Subject: [PATCH 07/25] updated ITS --- contracts/InterchainTokenService.sol | 13 ++++++------- contracts/test/Imports.sol | 2 +- scripts/deploy.js | 8 ++++---- test/InterchainTokenService.js | 22 ++-------------------- test/InterchainTokenServiceUpgradeFlow.js | 18 +++++++++++++++--- 5 files changed, 28 insertions(+), 35 deletions(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index cb517951..9a015097 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -22,7 +22,6 @@ import { IGatewayCaller } from './interfaces/IGatewayCaller.sol'; import { Create3AddressFixed } from './utils/Create3AddressFixed.sol'; import { Operator } from './utils/Operator.sol'; -import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; /** * @title The Interchain Token Service @@ -39,8 +38,8 @@ contract InterchainTokenService is Create3AddressFixed, ExpressExecutorTracker, InterchainAddressTracker, - AxelarGMPExecutableWithToken, - IInterchainTokenService + IInterchainTokenService, + AxelarGMPExecutableWithToken { using AddressBytes for bytes; using AddressBytes for address; @@ -382,7 +381,7 @@ contract InterchainTokenService is revert InvalidExpressMessageType(messageType); } - if (IAxelarGMPGatewayWithToken(gatewayAddress).isCommandExecuted(commandId)) revert AlreadyExecuted(); + if (gateway().isCommandExecuted(commandId)) revert AlreadyExecuted(); address expressExecutor = msg.sender; bytes32 payloadHash = keccak256(payload); @@ -676,7 +675,7 @@ contract InterchainTokenService is (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); if ( - validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(gatewayAddress).tokenAddresses(tokenSymbol) || + validTokenAddress(tokenId) != gateway().tokenAddresses(tokenSymbol) || amount != amountInPayload ) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } @@ -872,7 +871,7 @@ contract InterchainTokenService is string calldata sourceChain, string calldata sourceAddress, bytes calldata payload - ) internal override whenNotPaused { + ) internal override { bytes32 payloadHash = keccak256(payload); uint256 messageType; string memory originalSourceChain; @@ -898,7 +897,7 @@ contract InterchainTokenService is bytes calldata payload, string calldata tokenSymbol, uint256 amount - ) internal override whenNotPaused { + ) internal override { bytes32 payloadHash = keccak256(payload); uint256 messageType; string memory originalSourceChain; diff --git a/contracts/test/Imports.sol b/contracts/test/Imports.sol index 8281c493..7bd980b7 100644 --- a/contracts/test/Imports.sol +++ b/contracts/test/Imports.sol @@ -3,5 +3,5 @@ pragma solidity ^0.8.0; // solhint-disable no-unused-import -import { MockGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/test/mocks/MockGateway.sol'; +import { MockGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/test/mocks/MockGMPGatewayWithToken.sol'; import { AxelarGasService } from '@axelar-network/axelar-cgp-solidity/contracts/gas-service/AxelarGasService.sol'; diff --git a/scripts/deploy.js b/scripts/deploy.js index 1a32e3f0..51e73581 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -14,8 +14,8 @@ async function deployContract(wallet, contractName, args = []) { return contract; } -async function deployMockGateway(wallet) { - const gateway = await deployContract(wallet, 'MockGateway'); +async function deployMockGMPGatewayWithToken(wallet) { + const gateway = await deployContract(wallet, 'MockGMPGatewayWithToken'); return gateway; } @@ -87,7 +87,7 @@ async function deployAll( const create3Deployer = await new ethers.ContractFactory(Create3Deployer.abi, Create3Deployer.bytecode, wallet) .deploy() .then((d) => d.deployed()); - const gateway = await deployMockGateway(wallet); + const gateway = await deployMockGMPGatewayWithToken(wallet); const gasService = await deployGasService(wallet); const interchainTokenServiceAddress = await getCreate3Address(create3Deployer.address, wallet, deploymentKey); @@ -140,7 +140,7 @@ async function deployAll( module.exports = { deployContract, - deployMockGateway, + deployMockGMPGatewayWithToken, deployGasService, deployInterchainTokenService, deployAll, diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index dd3c7c22..98e2caab 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -419,7 +419,7 @@ describe('Interchain Token Service', () => { gasOptions, ), service, - 'ZeroAddress', + 'InvalidAddress', ); }); @@ -1342,7 +1342,7 @@ describe('Interchain Token Service', () => { await expectRevert( (gasOptions) => service.execute(commandId, sourceChain, wallet.address, '0x', gasOptions), service, - 'NotRemoteService', + 'InvalidPayload', ); }); @@ -1389,24 +1389,6 @@ describe('Interchain Token Service', () => { await deployFunctions.gateway(tokenName, tokenSymbol, tokenDecimals); }); - it('Should revert on execute with token if remote address validation fails', async () => { - const commandId = await approveContractCallWithMint( - gateway, - sourceChain, - wallet.address, - service.address, - '0x', - tokenSymbol, - amount, - ); - - await expectRevert( - (gasOptions) => service.executeWithToken(commandId, sourceChain, wallet.address, '0x', tokenSymbol, amount, gasOptions), - service, - 'NotRemoteService', - ); - }); - it('Should revert on execute with token if the service is paused', async () => { await service.setPauseStatus(true).then((tx) => tx.wait); diff --git a/test/InterchainTokenServiceUpgradeFlow.js b/test/InterchainTokenServiceUpgradeFlow.js index 858ba141..0fec61c2 100644 --- a/test/InterchainTokenServiceUpgradeFlow.js +++ b/test/InterchainTokenServiceUpgradeFlow.js @@ -11,7 +11,7 @@ const { const { getCreate3Address } = require('@axelar-network/axelar-gmp-sdk-solidity'); const { approveContractCall } = require('../scripts/utils'); const { isHardhat, waitFor, getRandomBytes32, getPayloadAndProposalHash, getContractJSON } = require('./utils'); -const { deployContract, deployMockGateway, deployGasService, deployInterchainTokenService } = require('../scripts/deploy'); +const { deployContract, deployMockGMPGatewayWithToken, deployGasService, deployInterchainTokenService } = require('../scripts/deploy'); const { getBytecodeHash } = require('@axelar-network/axelar-chains-config'); const AxelarServiceGovernance = getContractJSON('AxelarServiceGovernance'); const Create3Deployer = getContractJSON('Create3Deployer'); @@ -65,12 +65,14 @@ describe('Interchain Token Service Upgrade Flow', () => { buffer = isHardhat ? 10 * 60 * 60 : 10; + console.log("ahram1"); + const create3DeployerFactory = await ethers.getContractFactory(Create3Deployer.abi, Create3Deployer.bytecode, wallet); const create3Deployer = await create3DeployerFactory.deploy().then((d) => d.deployed()); const interchainTokenServiceAddress = await getCreate3Address(create3Deployer.address, wallet, deploymentKey); const interchainToken = await deployContract(wallet, 'InterchainToken', [interchainTokenServiceAddress]); - gateway = await deployMockGateway(wallet); + gateway = await deployMockGMPGatewayWithToken(wallet); gasService = await deployGasService(wallet); tokenManagerDeployer = await deployContract(wallet, 'TokenManagerDeployer', []); interchainTokenDeployer = await deployContract(wallet, 'InterchainTokenDeployer', [interchainToken.address]); @@ -85,6 +87,8 @@ describe('Interchain Token Service Upgrade Flow', () => { wallet, ); + console.log("ahram2"); + axelarServiceGovernance = await axelarServiceGovernanceFactory .deploy( gateway.address, @@ -96,6 +100,8 @@ describe('Interchain Token Service Upgrade Flow', () => { ) .then((d) => d.deployed()); + console.log("ahram3"); + service = await deployInterchainTokenService( wallet, create3Deployer.address, @@ -112,14 +118,18 @@ describe('Interchain Token Service Upgrade Flow', () => { deploymentKey, axelarServiceGovernance.address, ); + + console.log("ahram4"); }); - it('should upgrade Interchain Token Service through AxelarServiceGovernance timeLock proposal', async () => { + it.only('should upgrade Interchain Token Service through AxelarServiceGovernance timeLock proposal', async () => { const commandID = 0; const target = service.address; const nativeValue = 0; const timeDelay = isHardhat ? 12 * 60 * 60 : 12; + console.log("ahram5"); + const targetInterface = new Interface(service.interface.fragments); const newServiceImplementation = await deployContract(wallet, 'InterchainTokenService', [ tokenManagerDeployer.address, @@ -140,6 +150,8 @@ describe('Interchain Token Service Upgrade Flow', () => { setupParams, ]); + console.log(newServiceImplementationCodeHash); + const [payload, proposalHash, eta] = await getPayloadAndProposalHash(commandID, target, nativeValue, calldata, timeDelay); const commandIdGateway = getRandomBytes32(); From f4cedcb369864e0e673597f7eea8b2c2a098b818 Mon Sep 17 00:00:00 2001 From: ahramy Date: Fri, 23 Aug 2024 21:44:07 -0700 Subject: [PATCH 08/25] updated gateway --- contracts/test/Imports.sol | 4 +++- scripts/deploy.js | 8 ++++---- test/InterchainTokenServiceUpgradeFlow.js | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/contracts/test/Imports.sol b/contracts/test/Imports.sol index 7bd980b7..537dcdd7 100644 --- a/contracts/test/Imports.sol +++ b/contracts/test/Imports.sol @@ -3,5 +3,7 @@ pragma solidity ^0.8.0; // solhint-disable no-unused-import -import { MockGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/test/mocks/MockGMPGatewayWithToken.sol'; +import { MockGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/test/mocks/MockGateway.sol'; +// TODO: Do we need to have a separate unit test cases for GMPGatewayWithToken? +//import { MockGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/test/mocks/MockGMPGatewayWithToken.sol'; import { AxelarGasService } from '@axelar-network/axelar-cgp-solidity/contracts/gas-service/AxelarGasService.sol'; diff --git a/scripts/deploy.js b/scripts/deploy.js index 51e73581..1a32e3f0 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -14,8 +14,8 @@ async function deployContract(wallet, contractName, args = []) { return contract; } -async function deployMockGMPGatewayWithToken(wallet) { - const gateway = await deployContract(wallet, 'MockGMPGatewayWithToken'); +async function deployMockGateway(wallet) { + const gateway = await deployContract(wallet, 'MockGateway'); return gateway; } @@ -87,7 +87,7 @@ async function deployAll( const create3Deployer = await new ethers.ContractFactory(Create3Deployer.abi, Create3Deployer.bytecode, wallet) .deploy() .then((d) => d.deployed()); - const gateway = await deployMockGMPGatewayWithToken(wallet); + const gateway = await deployMockGateway(wallet); const gasService = await deployGasService(wallet); const interchainTokenServiceAddress = await getCreate3Address(create3Deployer.address, wallet, deploymentKey); @@ -140,7 +140,7 @@ async function deployAll( module.exports = { deployContract, - deployMockGMPGatewayWithToken, + deployMockGateway, deployGasService, deployInterchainTokenService, deployAll, diff --git a/test/InterchainTokenServiceUpgradeFlow.js b/test/InterchainTokenServiceUpgradeFlow.js index 0fec61c2..00a086b9 100644 --- a/test/InterchainTokenServiceUpgradeFlow.js +++ b/test/InterchainTokenServiceUpgradeFlow.js @@ -11,7 +11,7 @@ const { const { getCreate3Address } = require('@axelar-network/axelar-gmp-sdk-solidity'); const { approveContractCall } = require('../scripts/utils'); const { isHardhat, waitFor, getRandomBytes32, getPayloadAndProposalHash, getContractJSON } = require('./utils'); -const { deployContract, deployMockGMPGatewayWithToken, deployGasService, deployInterchainTokenService } = require('../scripts/deploy'); +const { deployContract, deployMockGateway, deployGasService, deployInterchainTokenService } = require('../scripts/deploy'); const { getBytecodeHash } = require('@axelar-network/axelar-chains-config'); const AxelarServiceGovernance = getContractJSON('AxelarServiceGovernance'); const Create3Deployer = getContractJSON('Create3Deployer'); @@ -72,7 +72,7 @@ describe('Interchain Token Service Upgrade Flow', () => { const interchainTokenServiceAddress = await getCreate3Address(create3Deployer.address, wallet, deploymentKey); const interchainToken = await deployContract(wallet, 'InterchainToken', [interchainTokenServiceAddress]); - gateway = await deployMockGMPGatewayWithToken(wallet); + gateway = await deployMockGateway(wallet); gasService = await deployGasService(wallet); tokenManagerDeployer = await deployContract(wallet, 'TokenManagerDeployer', []); interchainTokenDeployer = await deployContract(wallet, 'InterchainTokenDeployer', [interchainToken.address]); @@ -122,7 +122,7 @@ describe('Interchain Token Service Upgrade Flow', () => { console.log("ahram4"); }); - it.only('should upgrade Interchain Token Service through AxelarServiceGovernance timeLock proposal', async () => { + it('should upgrade Interchain Token Service through AxelarServiceGovernance timeLock proposal', async () => { const commandID = 0; const target = service.address; const nativeValue = 0; From 0136b2ba6435ba656c35acfd07e3bd78900d1d64 Mon Sep 17 00:00:00 2001 From: ahramy Date: Tue, 3 Sep 2024 11:12:56 -0700 Subject: [PATCH 09/25] updated unit tests --- contracts/InterchainTokenFactory.sol | 3 +- contracts/InterchainTokenService.sol | 21 +++++++---- .../interfaces/IInterchainTokenService.sol | 3 ++ test/InterchainTokenService.js | 14 +++++--- test/InterchainTokenServiceUpgradeFlow.js | 35 +++---------------- 5 files changed, 32 insertions(+), 44 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index 3fceb215..294416d4 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -6,7 +6,6 @@ import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/ import { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; - import { IInterchainTokenService } from './interfaces/IInterchainTokenService.sol'; import { IInterchainTokenFactory } from './interfaces/IInterchainTokenFactory.sol'; import { ITokenManagerType } from './interfaces/ITokenManagerType.sol'; @@ -40,7 +39,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M interchainTokenService = IInterchainTokenService(interchainTokenService_); chainNameHash = interchainTokenService.chainNameHash(); - gateway = interchainTokenService.gateway(); + gateway = interchainTokenService.getGatewayWithToken(); } /** diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 9a015097..9c6c2323 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; +import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; import { AxelarGMPExecutableWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutableWithToken.sol'; import { ExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; @@ -381,7 +382,7 @@ contract InterchainTokenService is revert InvalidExpressMessageType(messageType); } - if (gateway().isCommandExecuted(commandId)) revert AlreadyExecuted(); + if (gatewayWithToken().isCommandExecuted(commandId)) revert AlreadyExecuted(); address expressExecutor = msg.sender; bytes32 payloadHash = keccak256(payload); @@ -674,10 +675,8 @@ contract InterchainTokenService is function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - if ( - validTokenAddress(tokenId) != gateway().tokenAddresses(tokenSymbol) || - amount != amountInPayload - ) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); + if (validTokenAddress(tokenId) != gatewayWithToken().tokenAddresses(tokenSymbol) || amount != amountInPayload) + revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } /** @@ -871,7 +870,7 @@ contract InterchainTokenService is string calldata sourceChain, string calldata sourceAddress, bytes calldata payload - ) internal override { + ) internal override whenNotPaused { bytes32 payloadHash = keccak256(payload); uint256 messageType; string memory originalSourceChain; @@ -897,7 +896,7 @@ contract InterchainTokenService is bytes calldata payload, string calldata tokenSymbol, uint256 amount - ) internal override { + ) internal override whenNotPaused { bytes32 payloadHash = keccak256(payload); uint256 messageType; string memory originalSourceChain; @@ -1204,4 +1203,12 @@ contract InterchainTokenService is emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); } } + + /** + * @notice Returns the address of the IAxelarGMPGatewayWithToken contract. + * @return The Axelar GMP Gateway with Token instance. + */ + function getGatewayWithToken() external view returns (IAxelarGMPGatewayWithToken) { + return IAxelarGMPGatewayWithToken(gatewayAddress); + } } diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 150e0fba..3f141fd0 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; +import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; import { IAxelarValuedExpressExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarValuedExpressExecutable.sol'; import { IMulticall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol'; import { IPausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IPausable.sol'; @@ -94,6 +95,8 @@ interface IInterchainTokenService is ); event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); + function getGatewayWithToken() external view returns (IAxelarGMPGatewayWithToken); + /** * @notice Returns the address of the token manager deployer contract. * @return tokenManagerDeployerAddress The address of the token manager deployer contract. diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index 98e2caab..f077c7e0 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -495,6 +495,12 @@ describe('Interchain Token Service', () => { ); }); + it('Should return the correct contract id', async () => { + const expectedContractid = keccak256(toUtf8Bytes('interchain-token-service')); + const contractId = await service.contractId(); + expect(contractId).to.eq(expectedContractid); + }); + it('Should return the token manager implementation', async () => { const tokenManagerImplementation = await service.tokenManagerImplementation(getRandomInt(1000)); expect(tokenManagerImplementation).to.eq(tokenManager.address); @@ -1402,11 +1408,9 @@ describe('Interchain Token Service', () => { amount, ); - await expectRevert( - (gasOptions) => service.executeWithToken(commandId, sourceChain, sourceAddress, '0x', tokenSymbol, amount, gasOptions), - service, - 'Pause', - ); + await expect(service.executeWithToken(commandId, sourceChain, sourceAddress, '0x', tokenSymbol, amount)) + .to.be.revertedWithCustomError(gateway, 'MintFailed') + .withArgs('TS'); await service.setPauseStatus(false).then((tx) => tx.wait); }); diff --git a/test/InterchainTokenServiceUpgradeFlow.js b/test/InterchainTokenServiceUpgradeFlow.js index 00a086b9..5722986e 100644 --- a/test/InterchainTokenServiceUpgradeFlow.js +++ b/test/InterchainTokenServiceUpgradeFlow.js @@ -19,7 +19,7 @@ const Create3Deployer = getContractJSON('Create3Deployer'); const MINT_BURN = 4; describe('Interchain Token Service Upgrade Flow', () => { - let wallet, otherWallet, signer; + let wallet, otherWallet, multisig; let service, gateway, gasService; let tokenManagerDeployer, interchainTokenDeployer, tokenManager, tokenHandler, gatewayCaller; let interchainTokenFactoryAddress; @@ -31,7 +31,7 @@ describe('Interchain Token Service Upgrade Flow', () => { let buffer; const governanceChain = 'Governance Chain'; - const threshold = 2; + const minimumTimeDelay = isHardhat ? 10 * 60 * 60 : 15; const deploymentKey = 'InterchainTokenService'; const chainName = 'Test'; @@ -59,14 +59,11 @@ describe('Interchain Token Service Upgrade Flow', () => { } before(async () => { - [wallet, otherWallet, signer] = await ethers.getSigners(); - const signers = [wallet, otherWallet, signer]; + [wallet, otherWallet, multisig] = await ethers.getSigners(); governanceAddress = otherWallet.address; buffer = isHardhat ? 10 * 60 * 60 : 10; - console.log("ahram1"); - const create3DeployerFactory = await ethers.getContractFactory(Create3Deployer.abi, Create3Deployer.bytecode, wallet); const create3Deployer = await create3DeployerFactory.deploy().then((d) => d.deployed()); const interchainTokenServiceAddress = await getCreate3Address(create3Deployer.address, wallet, deploymentKey); @@ -87,21 +84,10 @@ describe('Interchain Token Service Upgrade Flow', () => { wallet, ); - console.log("ahram2"); - axelarServiceGovernance = await axelarServiceGovernanceFactory - .deploy( - gateway.address, - governanceChain, - governanceAddress, - buffer, - signers.map((signer) => signer.address), - threshold, - ) + .deploy(gateway.address, governanceChain, governanceAddress, minimumTimeDelay, multisig.address) .then((d) => d.deployed()); - console.log("ahram3"); - service = await deployInterchainTokenService( wallet, create3Deployer.address, @@ -118,8 +104,6 @@ describe('Interchain Token Service Upgrade Flow', () => { deploymentKey, axelarServiceGovernance.address, ); - - console.log("ahram4"); }); it('should upgrade Interchain Token Service through AxelarServiceGovernance timeLock proposal', async () => { @@ -128,8 +112,6 @@ describe('Interchain Token Service Upgrade Flow', () => { const nativeValue = 0; const timeDelay = isHardhat ? 12 * 60 * 60 : 12; - console.log("ahram5"); - const targetInterface = new Interface(service.interface.fragments); const newServiceImplementation = await deployContract(wallet, 'InterchainTokenService', [ tokenManagerDeployer.address, @@ -150,8 +132,6 @@ describe('Interchain Token Service Upgrade Flow', () => { setupParams, ]); - console.log(newServiceImplementationCodeHash); - const [payload, proposalHash, eta] = await getPayloadAndProposalHash(commandID, target, nativeValue, calldata, timeDelay); const commandIdGateway = getRandomBytes32(); @@ -240,12 +220,7 @@ describe('Interchain Token Service Upgrade Flow', () => { .to.emit(axelarServiceGovernance, 'MultisigApproved') .withArgs(proposalHash, target, calldata, nativeValue); - await axelarServiceGovernance - .connect(wallet) - .executeMultisigProposal(target, calldata, nativeValue) - .then((tx) => tx.wait); - - await expect(axelarServiceGovernance.connect(otherWallet).executeMultisigProposal(target, calldata, nativeValue)) + await expect(axelarServiceGovernance.connect(multisig).executeMultisigProposal(target, calldata, nativeValue)) .to.emit(axelarServiceGovernance, 'MultisigExecuted') .withArgs(proposalHash, target, calldata, nativeValue) .and.to.emit(service, 'Upgraded') From e4ff9c69f34efc588422ebc6e1bc8d595f0cb738 Mon Sep 17 00:00:00 2001 From: ahramy Date: Tue, 3 Sep 2024 14:27:41 -0700 Subject: [PATCH 10/25] updated --- test/InterchainTokenService.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index f077c7e0..e61a8da5 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -1395,6 +1395,22 @@ describe('Interchain Token Service', () => { await deployFunctions.gateway(tokenName, tokenSymbol, tokenDecimals); }); + it('Should revert on execute with token if mint token fails', async () => { + const commandId = await approveContractCallWithMint( + gateway, + sourceChain, + wallet.address, + service.address, + '0x', + tokenSymbol, + amount, + ); + + await expect(service.executeWithToken(commandId, sourceChain, wallet.address, '0x', tokenSymbol, amount )) + .to.be.revertedWithCustomError(gateway, 'MintFailed') + .withArgs('TS'); + }); + it('Should revert on execute with token if the service is paused', async () => { await service.setPauseStatus(true).then((tx) => tx.wait); From 1fe47014663dae666aeafbab60f883a0de059463 Mon Sep 17 00:00:00 2001 From: ahramy Date: Tue, 3 Sep 2024 14:32:21 -0700 Subject: [PATCH 11/25] added comments --- contracts/interfaces/IInterchainTokenService.sol | 4 ++++ contracts/test/Imports.sol | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 3f141fd0..13718d8e 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -95,6 +95,10 @@ interface IInterchainTokenService is ); event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); + /** + * @notice Returns the address of the IAxelarGMPGatewayWithToken contract. + * @return The Axelar GMP Gateway with Token instance. + */ function getGatewayWithToken() external view returns (IAxelarGMPGatewayWithToken); /** diff --git a/contracts/test/Imports.sol b/contracts/test/Imports.sol index 537dcdd7..8281c493 100644 --- a/contracts/test/Imports.sol +++ b/contracts/test/Imports.sol @@ -4,6 +4,4 @@ pragma solidity ^0.8.0; // solhint-disable no-unused-import import { MockGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/test/mocks/MockGateway.sol'; -// TODO: Do we need to have a separate unit test cases for GMPGatewayWithToken? -//import { MockGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/test/mocks/MockGMPGatewayWithToken.sol'; import { AxelarGasService } from '@axelar-network/axelar-cgp-solidity/contracts/gas-service/AxelarGasService.sol'; From 3f1dbf68e9be22ae57888a4e7cb3351973474787 Mon Sep 17 00:00:00 2001 From: ahramy Date: Tue, 3 Sep 2024 14:48:56 -0700 Subject: [PATCH 12/25] package json --- package.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2ff7cf24..6d32ffc6 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,11 @@ "node": ">=18" }, "dependencies": { - "@axelar-network/axelar-cgp-solidity": "6.2.1", - "@axelar-network/axelar-gmp-sdk-solidity": "5.6.4" + "@axelar-network/axelar-cgp-solidity": "file:../axelar-cgp-solidity", + "@axelar-network/axelar-gmp-sdk-solidity": "file:../axelar-gmp-sdk-solidity", + "build": "^0.1.4", + "npm": "^10.8.3", + "run": "^1.5.0" }, "devDependencies": { "@axelar-network/axelar-chains-config": "^1.2.0", From c91a6cd6b53b9a553f57b2ea6f67ae419b4dd6b6 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 11:44:36 -0700 Subject: [PATCH 13/25] addressed comments --- contracts/InterchainTokenFactory.sol | 2 +- contracts/InterchainTokenService.sol | 84 +++++++++++++------ .../interfaces/IInterchainTokenService.sol | 7 -- package.json | 7 +- test/InterchainTokenService.js | 20 +++-- 5 files changed, 72 insertions(+), 48 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index 294416d4..c95a83ad 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -39,7 +39,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M interchainTokenService = IInterchainTokenService(interchainTokenService_); chainNameHash = interchainTokenService.chainNameHash(); - gateway = interchainTokenService.getGatewayWithToken(); + gateway = IAxelarGMPGatewayWithToken(address(interchainTokenService.gateway())); } /** diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 9c6c2323..fadc7894 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -4,14 +4,15 @@ pragma solidity ^0.8.0; import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; +import { IAxelarGMPGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGateway.sol'; import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; -import { AxelarGMPExecutableWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutableWithToken.sol'; import { ExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol'; import { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol'; import { Pausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Pausable.sol'; import { InterchainAddressTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/InterchainAddressTracker.sol'; + import { IInterchainTokenService } from './interfaces/IInterchainTokenService.sol'; import { ITokenHandler } from './interfaces/ITokenHandler.sol'; import { ITokenManagerDeployer } from './interfaces/ITokenManagerDeployer.sol'; @@ -21,7 +22,6 @@ import { IInterchainTokenExpressExecutable } from './interfaces/IInterchainToken import { ITokenManager } from './interfaces/ITokenManager.sol'; import { IGatewayCaller } from './interfaces/IGatewayCaller.sol'; import { Create3AddressFixed } from './utils/Create3AddressFixed.sol'; - import { Operator } from './utils/Operator.sol'; /** @@ -39,12 +39,12 @@ contract InterchainTokenService is Create3AddressFixed, ExpressExecutorTracker, InterchainAddressTracker, - IInterchainTokenService, - AxelarGMPExecutableWithToken + IInterchainTokenService { using AddressBytes for bytes; using AddressBytes for address; + IAxelarGMPGatewayWithToken public immutable gatewayAddress; IAxelarGasService public immutable gasService; address public immutable interchainTokenFactory; bytes32 public immutable chainNameHash; @@ -124,7 +124,7 @@ contract InterchainTokenService is address tokenManagerImplementation_, address tokenHandler_, address gatewayCaller_ - ) AxelarGMPExecutableWithToken(gateway_) { + ) { if ( gasService_ == address(0) || tokenManagerDeployer_ == address(0) || @@ -136,6 +136,7 @@ contract InterchainTokenService is gatewayCaller_ == address(0) ) revert ZeroAddress(); + gatewayAddress = IAxelarGMPGatewayWithToken(gateway_); gasService = IAxelarGasService(gasService_); tokenManagerDeployer = tokenManagerDeployer_; interchainTokenDeployer = interchainTokenDeployer_; @@ -382,7 +383,7 @@ contract InterchainTokenService is revert InvalidExpressMessageType(messageType); } - if (gatewayWithToken().isCommandExecuted(commandId)) revert AlreadyExecuted(); + if (gatewayAddress.isCommandExecuted(commandId)) revert AlreadyExecuted(); address expressExecutor = msg.sender; bytes32 payloadHash = keccak256(payload); @@ -621,6 +622,26 @@ contract InterchainTokenService is } } + /** + * @notice Executes operations based on the payload and selector. + * @param commandId The unique message id. + * @param sourceChain The chain where the transaction originates from. + * @param sourceAddress The address of the remote ITS where the transaction originates from. + * @param payload The encoded data payload for the transaction. + */ + function execute( + bytes32 commandId, + string calldata sourceChain, + string calldata sourceAddress, + bytes calldata payload + ) external onlyRemoteService(sourceChain, sourceAddress) whenNotPaused { + bytes32 payloadHash = keccak256(payload); + + if (!gatewayAddress.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); + + _execute(commandId, sourceChain, sourceAddress, payload, payloadHash); + } + /** * @notice Returns the amount of token that this call is worth. * @dev If `tokenAddress` is `0`, then value is in terms of the native token, otherwise it's in terms of the token address. @@ -665,6 +686,17 @@ contract InterchainTokenService is expressExecute(commandId, sourceChain, sourceAddress, payload); } + function executeWithToken( + bytes32 commandId, + string calldata sourceChain, + string calldata sourceAddress, + bytes calldata payload, + string calldata tokenSymbol, + uint256 amount + ) external onlyRemoteService(sourceChain, sourceAddress) whenNotPaused { + _executeWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount); + } + /** * @notice Check that the tokenId from the payload is a token that is registered in the gateway with the proper tokenSymbol, with the right amount from the payload. * Also check that the amount in the payload matches the one for the call. @@ -675,7 +707,7 @@ contract InterchainTokenService is function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - if (validTokenAddress(tokenId) != gatewayWithToken().tokenAddresses(tokenSymbol) || amount != amountInPayload) + if (validTokenAddress(tokenId) != gatewayAddress.tokenAddresses(tokenSymbol) || amount != amountInPayload) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } @@ -869,21 +901,20 @@ contract InterchainTokenService is bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, - bytes calldata payload - ) internal override whenNotPaused { - bytes32 payloadHash = keccak256(payload); + bytes memory payload, + bytes32 payloadHash + ) internal { uint256 messageType; string memory originalSourceChain; - bytes memory originalPayload; - (messageType, originalSourceChain, originalPayload) = _getExecuteParams(sourceChain, payload); + (messageType, originalSourceChain, payload) = _getExecuteParams(sourceChain, payload); if (messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER) { address expressExecutor = _getExpressExecutorAndEmitEvent(commandId, sourceChain, sourceAddress, payloadHash); - _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, originalPayload); + _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, payload); } else if (messageType == MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER) { - _processDeployTokenManagerPayload(originalPayload); + _processDeployTokenManagerPayload(payload); } else if (messageType == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN) { - _processDeployInterchainTokenPayload(originalPayload); + _processDeployInterchainTokenPayload(payload); } else { revert InvalidMessageType(messageType); } @@ -893,26 +924,29 @@ contract InterchainTokenService is bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, - bytes calldata payload, + bytes memory payload, string calldata tokenSymbol, uint256 amount - ) internal override whenNotPaused { + ) internal { bytes32 payloadHash = keccak256(payload); + + if (!gatewayAddress.validateContractCallAndMint(commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount)) + revert NotApprovedByGateway(); + uint256 messageType; string memory originalSourceChain; - bytes memory originalPayload; - (messageType, originalSourceChain, originalPayload) = _getExecuteParams(sourceChain, payload); + (messageType, originalSourceChain, payload) = _getExecuteParams(sourceChain, payload); if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) { revert InvalidMessageType(messageType); } - _checkPayloadAgainstGatewayData(originalPayload, tokenSymbol, amount); + _checkPayloadAgainstGatewayData(payload, tokenSymbol, amount); // slither-disable-next-line reentrancy-events address expressExecutor = _getExpressExecutorAndEmitEvent(commandId, sourceChain, sourceAddress, payloadHash); - _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, originalPayload); + _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, payload); } function _getMessageType(bytes memory payload) internal pure returns (uint256 messageType) { @@ -1204,11 +1238,7 @@ contract InterchainTokenService is } } - /** - * @notice Returns the address of the IAxelarGMPGatewayWithToken contract. - * @return The Axelar GMP Gateway with Token instance. - */ - function getGatewayWithToken() external view returns (IAxelarGMPGatewayWithToken) { - return IAxelarGMPGatewayWithToken(gatewayAddress); + function gateway() external view override returns (IAxelarGMPGateway) { + return IAxelarGMPGateway(gatewayAddress); } } diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 13718d8e..150e0fba 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.0; -import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; import { IAxelarValuedExpressExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarValuedExpressExecutable.sol'; import { IMulticall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol'; import { IPausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IPausable.sol'; @@ -95,12 +94,6 @@ interface IInterchainTokenService is ); event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); - /** - * @notice Returns the address of the IAxelarGMPGatewayWithToken contract. - * @return The Axelar GMP Gateway with Token instance. - */ - function getGatewayWithToken() external view returns (IAxelarGMPGatewayWithToken); - /** * @notice Returns the address of the token manager deployer contract. * @return tokenManagerDeployerAddress The address of the token manager deployer contract. diff --git a/package.json b/package.json index 6d32ffc6..65204a3b 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,8 @@ "node": ">=18" }, "dependencies": { - "@axelar-network/axelar-cgp-solidity": "file:../axelar-cgp-solidity", - "@axelar-network/axelar-gmp-sdk-solidity": "file:../axelar-gmp-sdk-solidity", - "build": "^0.1.4", - "npm": "^10.8.3", - "run": "^1.5.0" + "@axelar-network/axelar-cgp-solidity": "6.3.1", + "@axelar-network/axelar-gmp-sdk-solidity": "5.11.0" }, "devDependencies": { "@axelar-network/axelar-chains-config": "^1.2.0", diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index e61a8da5..28449c7a 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -419,7 +419,7 @@ describe('Interchain Token Service', () => { gasOptions, ), service, - 'InvalidAddress', + 'ZeroAddress', ); }); @@ -1348,7 +1348,7 @@ describe('Interchain Token Service', () => { await expectRevert( (gasOptions) => service.execute(commandId, sourceChain, wallet.address, '0x', gasOptions), service, - 'InvalidPayload', + 'NotRemoteService', ); }); @@ -1406,9 +1406,11 @@ describe('Interchain Token Service', () => { amount, ); - await expect(service.executeWithToken(commandId, sourceChain, wallet.address, '0x', tokenSymbol, amount )) - .to.be.revertedWithCustomError(gateway, 'MintFailed') - .withArgs('TS'); + await expectRevert( + (gasOptions) => service.executeWithToken(commandId, sourceChain, wallet.address, '0x', tokenSymbol, amount, gasOptions), + service, + 'NotRemoteService', + ); }); it('Should revert on execute with token if the service is paused', async () => { @@ -1424,9 +1426,11 @@ describe('Interchain Token Service', () => { amount, ); - await expect(service.executeWithToken(commandId, sourceChain, sourceAddress, '0x', tokenSymbol, amount)) - .to.be.revertedWithCustomError(gateway, 'MintFailed') - .withArgs('TS'); + await expectRevert( + (gasOptions) => service.executeWithToken(commandId, sourceChain, sourceAddress, '0x', tokenSymbol, amount, gasOptions), + service, + 'Pause', + ); await service.setPauseStatus(false).then((tx) => tx.wait); }); From 8c57a74ceb9851c3f342880a8636eb47ae218e71 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 11:46:17 -0700 Subject: [PATCH 14/25] updated unit test description --- test/InterchainTokenService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index 28449c7a..aa2fba52 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -1395,7 +1395,7 @@ describe('Interchain Token Service', () => { await deployFunctions.gateway(tokenName, tokenSymbol, tokenDecimals); }); - it('Should revert on execute with token if mint token fails', async () => { + it('Should revert on execute with token if remote address validation fails', async () => { const commandId = await approveContractCallWithMint( gateway, sourceChain, From 14f4c06e76be53b579db4b5ae3d98693f09f4d0b Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 19:38:48 -0700 Subject: [PATCH 15/25] update --- contracts/InterchainTokenService.sol | 16 ++++++---------- contracts/utils/GatewayCaller.sol | 7 ++++--- test/InterchainTokenServiceUpgradeFlow.js | 8 ++++---- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index fadc7894..f80fe798 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -44,7 +44,7 @@ contract InterchainTokenService is using AddressBytes for bytes; using AddressBytes for address; - IAxelarGMPGatewayWithToken public immutable gatewayAddress; + IAxelarGMPGateway public immutable gateway; IAxelarGasService public immutable gasService; address public immutable interchainTokenFactory; bytes32 public immutable chainNameHash; @@ -136,7 +136,7 @@ contract InterchainTokenService is gatewayCaller_ == address(0) ) revert ZeroAddress(); - gatewayAddress = IAxelarGMPGatewayWithToken(gateway_); + gateway = IAxelarGMPGateway(gateway_); gasService = IAxelarGasService(gasService_); tokenManagerDeployer = tokenManagerDeployer_; interchainTokenDeployer = interchainTokenDeployer_; @@ -383,7 +383,7 @@ contract InterchainTokenService is revert InvalidExpressMessageType(messageType); } - if (gatewayAddress.isCommandExecuted(commandId)) revert AlreadyExecuted(); + if (gateway.isCommandExecuted(commandId)) revert AlreadyExecuted(); address expressExecutor = msg.sender; bytes32 payloadHash = keccak256(payload); @@ -637,7 +637,7 @@ contract InterchainTokenService is ) external onlyRemoteService(sourceChain, sourceAddress) whenNotPaused { bytes32 payloadHash = keccak256(payload); - if (!gatewayAddress.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); + if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); _execute(commandId, sourceChain, sourceAddress, payload, payloadHash); } @@ -707,7 +707,7 @@ contract InterchainTokenService is function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - if (validTokenAddress(tokenId) != gatewayAddress.tokenAddresses(tokenSymbol) || amount != amountInPayload) + if (validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(address(gateway)).tokenAddresses(tokenSymbol) || amount != amountInPayload) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } @@ -930,7 +930,7 @@ contract InterchainTokenService is ) internal { bytes32 payloadHash = keccak256(payload); - if (!gatewayAddress.validateContractCallAndMint(commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount)) + if (!IAxelarGMPGatewayWithToken(address(gateway)).validateContractCallAndMint(commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount)) revert NotApprovedByGateway(); uint256 messageType; @@ -1237,8 +1237,4 @@ contract InterchainTokenService is emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); } } - - function gateway() external view override returns (IAxelarGMPGateway) { - return IAxelarGMPGateway(gatewayAddress); - } } diff --git a/contracts/utils/GatewayCaller.sol b/contracts/utils/GatewayCaller.sol index 2a8bc40f..921f3a87 100644 --- a/contracts/utils/GatewayCaller.sol +++ b/contracts/utils/GatewayCaller.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; +import { IAxelarGMPGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGateway.sol'; import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; import { IGatewayCaller } from '../interfaces/IGatewayCaller.sol'; @@ -11,7 +12,7 @@ import { IGatewayCaller } from '../interfaces/IGatewayCaller.sol'; * @dev This contract is used to handle cross-chain ITS calls via the Axelar gateway. */ contract GatewayCaller is IGatewayCaller { - IAxelarGMPGatewayWithToken public immutable gateway; + IAxelarGMPGateway public immutable gateway; IAxelarGasService public immutable gasService; /** @@ -20,7 +21,7 @@ contract GatewayCaller is IGatewayCaller { * @param gasService_ The address of the AxelarGasService contract */ constructor(address gateway_, address gasService_) { - gateway = IAxelarGMPGatewayWithToken(gateway_); + gateway = IAxelarGMPGateway(gateway_); gasService = IAxelarGasService(gasService_); } @@ -117,6 +118,6 @@ contract GatewayCaller is IGatewayCaller { } } - gateway.callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount); + IAxelarGMPGatewayWithToken(address(gateway)).callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount); } } diff --git a/test/InterchainTokenServiceUpgradeFlow.js b/test/InterchainTokenServiceUpgradeFlow.js index 5722986e..76e4f235 100644 --- a/test/InterchainTokenServiceUpgradeFlow.js +++ b/test/InterchainTokenServiceUpgradeFlow.js @@ -19,7 +19,7 @@ const Create3Deployer = getContractJSON('Create3Deployer'); const MINT_BURN = 4; describe('Interchain Token Service Upgrade Flow', () => { - let wallet, otherWallet, multisig; + let wallet, otherWallet, operator; let service, gateway, gasService; let tokenManagerDeployer, interchainTokenDeployer, tokenManager, tokenHandler, gatewayCaller; let interchainTokenFactoryAddress; @@ -59,7 +59,7 @@ describe('Interchain Token Service Upgrade Flow', () => { } before(async () => { - [wallet, otherWallet, multisig] = await ethers.getSigners(); + [wallet, otherWallet, operator] = await ethers.getSigners(); governanceAddress = otherWallet.address; buffer = isHardhat ? 10 * 60 * 60 : 10; @@ -85,7 +85,7 @@ describe('Interchain Token Service Upgrade Flow', () => { ); axelarServiceGovernance = await axelarServiceGovernanceFactory - .deploy(gateway.address, governanceChain, governanceAddress, minimumTimeDelay, multisig.address) + .deploy(gateway.address, governanceChain, governanceAddress, minimumTimeDelay, operator.address) .then((d) => d.deployed()); service = await deployInterchainTokenService( @@ -220,7 +220,7 @@ describe('Interchain Token Service Upgrade Flow', () => { .to.emit(axelarServiceGovernance, 'MultisigApproved') .withArgs(proposalHash, target, calldata, nativeValue); - await expect(axelarServiceGovernance.connect(multisig).executeMultisigProposal(target, calldata, nativeValue)) + await expect(axelarServiceGovernance.connect(operator).executeMultisigProposal(target, calldata, nativeValue)) .to.emit(axelarServiceGovernance, 'MultisigExecuted') .withArgs(proposalHash, target, calldata, nativeValue) .and.to.emit(service, 'Upgraded') From a5a9a17a2a375c6ed5dadf8750b17a1acd16de99 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 19:54:09 -0700 Subject: [PATCH 16/25] updated comments --- contracts/InterchainTokenService.sol | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index f80fe798..c6430179 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -44,6 +44,13 @@ contract InterchainTokenService is using AddressBytes for bytes; using AddressBytes for address; + /** + * @dev Axelar GMP Gateway for cross-chain messaging. + * Two available approaches: + * 1. Pure GMP: Uses IAxelarGMPGateway to handle messaging without token transfers, compatible across Amplifier chains. + * 2. GMP with Token: Legacy functionality. Explicitly cast to IAxelarGMPGatewayWithToken when needed. + * This approach only functions on chains that rely on Axelar consensus Connection. + */ IAxelarGMPGateway public immutable gateway; IAxelarGasService public immutable gasService; address public immutable interchainTokenFactory; From 33f616adae33a298c35ee8f0d3829a38384acaba Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 5 Sep 2024 19:54:56 -0700 Subject: [PATCH 17/25] lint and prettier --- contracts/InterchainTokenService.sol | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index c6430179..4166208a 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -714,8 +714,10 @@ contract InterchainTokenService is function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - if (validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(address(gateway)).tokenAddresses(tokenSymbol) || amount != amountInPayload) - revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); + if ( + validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(address(gateway)).tokenAddresses(tokenSymbol) || + amount != amountInPayload + ) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } /** @@ -937,8 +939,16 @@ contract InterchainTokenService is ) internal { bytes32 payloadHash = keccak256(payload); - if (!IAxelarGMPGatewayWithToken(address(gateway)).validateContractCallAndMint(commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount)) - revert NotApprovedByGateway(); + if ( + !IAxelarGMPGatewayWithToken(address(gateway)).validateContractCallAndMint( + commandId, + sourceChain, + sourceAddress, + payloadHash, + tokenSymbol, + amount + ) + ) revert NotApprovedByGateway(); uint256 messageType; string memory originalSourceChain; From 1c96e8565da2578285b7d61a275e276eaf7e452c Mon Sep 17 00:00:00 2001 From: ahramy Date: Fri, 6 Sep 2024 00:23:35 -0700 Subject: [PATCH 18/25] updated --- contracts/InterchainTokenService.sol | 33 ++++++++++++---------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 4166208a..0283f704 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -45,11 +45,12 @@ contract InterchainTokenService is using AddressBytes for address; /** - * @dev Axelar GMP Gateway for cross-chain messaging. - * Two available approaches: - * 1. Pure GMP: Uses IAxelarGMPGateway to handle messaging without token transfers, compatible across Amplifier chains. - * 2. GMP with Token: Legacy functionality. Explicitly cast to IAxelarGMPGatewayWithToken when needed. - * This approach only functions on chains that rely on Axelar consensus Connection. + * @dev There are two types of Axelar Gateways for cross-chain messaging: + * 1. Cross-chain messaging (GMP): The Axelar Gateway allows sending cross-chain messages. + * This is compatible across both Amplifier and consensus chains. IAxelarGMPGateway interface exposes this functionality. + * 2. Cross-chain messaging with Gateway Token: The AxelarGateway on legacy consensus EVM connections supports this (via callContractWithToken) + * but not Amplifier chains. The gateway is cast to IAxelarGMPGatewayWithToken when gateway tokens need to be handled. + * ITS deployments on Amplifier chains will revert when this functionality is used. */ IAxelarGMPGateway public immutable gateway; IAxelarGasService public immutable gasService; @@ -714,10 +715,8 @@ contract InterchainTokenService is function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - if ( - validTokenAddress(tokenId) != IAxelarGMPGatewayWithToken(address(gateway)).tokenAddresses(tokenSymbol) || - amount != amountInPayload - ) revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); + if (validTokenAddress(tokenId) != gatewayWithToken().tokenAddresses(tokenSymbol) || amount != amountInPayload) + revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); } /** @@ -939,16 +938,8 @@ contract InterchainTokenService is ) internal { bytes32 payloadHash = keccak256(payload); - if ( - !IAxelarGMPGatewayWithToken(address(gateway)).validateContractCallAndMint( - commandId, - sourceChain, - sourceAddress, - payloadHash, - tokenSymbol, - amount - ) - ) revert NotApprovedByGateway(); + if (!gatewayWithToken().validateContractCallAndMint(commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount)) + revert NotApprovedByGateway(); uint256 messageType; string memory originalSourceChain; @@ -1254,4 +1245,8 @@ contract InterchainTokenService is emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); } } + + function gatewayWithToken() internal view returns (IAxelarGMPGatewayWithToken) { + return IAxelarGMPGatewayWithToken(address(gateway)); + } } From 6a4379fc049292fd80be70edb9a8a3e9e5df900a Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 10 Oct 2024 09:10:50 -0700 Subject: [PATCH 19/25] removed GMP naming --- contracts/InterchainTokenFactory.sol | 6 +++--- contracts/InterchainTokenService.sol | 16 ++++++++-------- contracts/utils/GatewayCaller.sol | 10 +++++----- package.json | 2 +- test/InterchainTokenServiceUpgradeFlow.js | 6 +++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index c95a83ad..0e0f7bfe 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol'; import { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; -import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; +import { IAxelarGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGatewayWithToken.sol'; import { IInterchainTokenService } from './interfaces/IInterchainTokenService.sol'; import { IInterchainTokenFactory } from './interfaces/IInterchainTokenFactory.sol'; import { ITokenManagerType } from './interfaces/ITokenManagerType.sol'; @@ -21,7 +21,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M IInterchainTokenService public immutable interchainTokenService; bytes32 public immutable chainNameHash; - IAxelarGMPGatewayWithToken public immutable gateway; + IAxelarGatewayWithToken public immutable gateway; bytes32 private constant CONTRACT_ID = keccak256('interchain-token-factory'); bytes32 internal constant PREFIX_CANONICAL_TOKEN_SALT = keccak256('canonical-token-salt'); @@ -39,7 +39,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M interchainTokenService = IInterchainTokenService(interchainTokenService_); chainNameHash = interchainTokenService.chainNameHash(); - gateway = IAxelarGMPGatewayWithToken(address(interchainTokenService.gateway())); + gateway = IAxelarGatewayWithToken(address(interchainTokenService.gateway())); } /** diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 0283f704..5a7cfa46 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; -import { IAxelarGMPGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGateway.sol'; -import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; +import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol'; +import { IAxelarGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGatewayWithToken.sol'; import { ExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol'; @@ -47,12 +47,12 @@ contract InterchainTokenService is /** * @dev There are two types of Axelar Gateways for cross-chain messaging: * 1. Cross-chain messaging (GMP): The Axelar Gateway allows sending cross-chain messages. - * This is compatible across both Amplifier and consensus chains. IAxelarGMPGateway interface exposes this functionality. + * This is compatible across both Amplifier and consensus chains. IAxelarGateway interface exposes this functionality. * 2. Cross-chain messaging with Gateway Token: The AxelarGateway on legacy consensus EVM connections supports this (via callContractWithToken) - * but not Amplifier chains. The gateway is cast to IAxelarGMPGatewayWithToken when gateway tokens need to be handled. + * but not Amplifier chains. The gateway is cast to IAxelarGatewayWithToken when gateway tokens need to be handled. * ITS deployments on Amplifier chains will revert when this functionality is used. */ - IAxelarGMPGateway public immutable gateway; + IAxelarGateway public immutable gateway; IAxelarGasService public immutable gasService; address public immutable interchainTokenFactory; bytes32 public immutable chainNameHash; @@ -144,7 +144,7 @@ contract InterchainTokenService is gatewayCaller_ == address(0) ) revert ZeroAddress(); - gateway = IAxelarGMPGateway(gateway_); + gateway = IAxelarGateway(gateway_); gasService = IAxelarGasService(gasService_); tokenManagerDeployer = tokenManagerDeployer_; interchainTokenDeployer = interchainTokenDeployer_; @@ -1246,7 +1246,7 @@ contract InterchainTokenService is } } - function gatewayWithToken() internal view returns (IAxelarGMPGatewayWithToken) { - return IAxelarGMPGatewayWithToken(address(gateway)); + function gatewayWithToken() internal view returns (IAxelarGatewayWithToken) { + return IAxelarGatewayWithToken(address(gateway)); } } diff --git a/contracts/utils/GatewayCaller.sol b/contracts/utils/GatewayCaller.sol index 921f3a87..df81612c 100644 --- a/contracts/utils/GatewayCaller.sol +++ b/contracts/utils/GatewayCaller.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol'; -import { IAxelarGMPGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGateway.sol'; -import { IAxelarGMPGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGatewayWithToken.sol'; +import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol'; +import { IAxelarGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGatewayWithToken.sol'; import { IGatewayCaller } from '../interfaces/IGatewayCaller.sol'; /** @@ -12,7 +12,7 @@ import { IGatewayCaller } from '../interfaces/IGatewayCaller.sol'; * @dev This contract is used to handle cross-chain ITS calls via the Axelar gateway. */ contract GatewayCaller is IGatewayCaller { - IAxelarGMPGateway public immutable gateway; + IAxelarGateway public immutable gateway; IAxelarGasService public immutable gasService; /** @@ -21,7 +21,7 @@ contract GatewayCaller is IGatewayCaller { * @param gasService_ The address of the AxelarGasService contract */ constructor(address gateway_, address gasService_) { - gateway = IAxelarGMPGateway(gateway_); + gateway = IAxelarGateway(gateway_); gasService = IAxelarGasService(gasService_); } @@ -118,6 +118,6 @@ contract GatewayCaller is IGatewayCaller { } } - IAxelarGMPGatewayWithToken(address(gateway)).callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount); + IAxelarGatewayWithToken(address(gateway)).callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount); } } diff --git a/package.json b/package.json index 65204a3b..6b6f2afb 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "dependencies": { "@axelar-network/axelar-cgp-solidity": "6.3.1", - "@axelar-network/axelar-gmp-sdk-solidity": "5.11.0" + "@axelar-network/axelar-gmp-sdk-solidity": "6.0.0" }, "devDependencies": { "@axelar-network/axelar-chains-config": "^1.2.0", diff --git a/test/InterchainTokenServiceUpgradeFlow.js b/test/InterchainTokenServiceUpgradeFlow.js index 76e4f235..192102b3 100644 --- a/test/InterchainTokenServiceUpgradeFlow.js +++ b/test/InterchainTokenServiceUpgradeFlow.js @@ -217,11 +217,11 @@ describe('Interchain Token Service Upgrade Flow', () => { ); await expect(axelarServiceGovernance.execute(commandIdGateway, governanceChain, governanceAddress, payload)) - .to.emit(axelarServiceGovernance, 'MultisigApproved') + .to.emit(axelarServiceGovernance, 'OperatorProposalApproved') .withArgs(proposalHash, target, calldata, nativeValue); - await expect(axelarServiceGovernance.connect(operator).executeMultisigProposal(target, calldata, nativeValue)) - .to.emit(axelarServiceGovernance, 'MultisigExecuted') + await expect(axelarServiceGovernance.connect(operator).executeOperatorProposal(target, calldata, nativeValue)) + .to.emit(axelarServiceGovernance, 'OperatorProposalExecuted') .withArgs(proposalHash, target, calldata, nativeValue) .and.to.emit(service, 'Upgraded') .withArgs(newServiceImplementation.address); From bbbd8349c06d095d6f88863f6ee0f5aca613d58a Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 10 Oct 2024 14:54:48 -0700 Subject: [PATCH 20/25] remove override --- contracts/InterchainTokenService.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index 5a7cfa46..f62d2e21 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -385,7 +385,7 @@ contract InterchainTokenService is string calldata sourceChain, string calldata sourceAddress, bytes calldata payload - ) public payable override whenNotPaused { + ) public payable whenNotPaused { uint256 messageType = abi.decode(payload, (uint256)); if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) { revert InvalidExpressMessageType(messageType); From 0179ed735c9f1bf1dc35907415d9d439e9b0219d Mon Sep 17 00:00:00 2001 From: ahramy Date: Tue, 15 Oct 2024 22:05:27 -0700 Subject: [PATCH 21/25] update package-lock.json --- package-lock.json | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d175e75..f675a1e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "2.0.0", "license": "MIT", "dependencies": { - "@axelar-network/axelar-cgp-solidity": "6.2.1", - "@axelar-network/axelar-gmp-sdk-solidity": "5.6.4" + "@axelar-network/axelar-cgp-solidity": "6.3.1", + "@axelar-network/axelar-gmp-sdk-solidity": "6.0.0" }, "devDependencies": { "@axelar-network/axelar-chains-config": "^1.2.0", @@ -50,14 +50,22 @@ "dev": true }, "node_modules/@axelar-network/axelar-cgp-solidity": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@axelar-network/axelar-cgp-solidity/-/axelar-cgp-solidity-6.2.1.tgz", - "integrity": "sha512-0RaxLYmsp3elXBytn7+eZUil1KFS6jjHR/ECrN/3IC7TeTDPUYunyy6JDxCdNYNtiD6EKgUAfQ7G4DrBb6hRxg==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@axelar-network/axelar-cgp-solidity/-/axelar-cgp-solidity-6.3.1.tgz", + "integrity": "sha512-RJmcOQbj2VhQb8uqBtu0beNj4MKRVjiYj74wXu6QI/a4bJ5EwwZK3+uCbTVNM9Qc7LqJqObhtGQfKUnAXEFCHA==", "dependencies": { - "@axelar-network/axelar-gmp-sdk-solidity": "5.6.4" + "@axelar-network/axelar-gmp-sdk-solidity": "5.8.0" }, "engines": { - "node": ">=16" + "node": ">=18" + } + }, + "node_modules/@axelar-network/axelar-cgp-solidity/node_modules/@axelar-network/axelar-gmp-sdk-solidity": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-5.8.0.tgz", + "integrity": "sha512-ThiCWK7lhwmsipgjKkw8c0z0ubB9toRMV9X0tRVOXHHSknKp5DCFfatbCwjpSC5GZRa+61ciTSqJNtCc7j9YoQ==", + "engines": { + "node": ">=18" } }, "node_modules/@axelar-network/axelar-chains-config": { @@ -71,11 +79,11 @@ } }, "node_modules/@axelar-network/axelar-gmp-sdk-solidity": { - "version": "5.6.4", - "resolved": "https://registry.npmjs.org/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-5.6.4.tgz", - "integrity": "sha512-PQjV+HeJynmSRMhyM3SexwnbFNruSaiRUeNCWjV8/7CkdPsDqypoqIXVRVU8Zk92DUUHeqZZzL/3qP2LYuvlnA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-6.0.0.tgz", + "integrity": "sha512-skmHwbvYOkyuIrL5twVDlRNbyDAWQXcPGGufSMhBZ125iy85TAti76EFayoyfFXvLsq3BnKE8D+D1iC2mXB5eA==", "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@axelarjs/evm": { From d670e7e5b0cd2a63bfbec858e846227e0859e74d Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 17 Oct 2024 10:49:58 -0700 Subject: [PATCH 22/25] updated cgp solidity version to 6.4.0 --- package-lock.json | 16 ++++++++-------- package.json | 2 +- test/InterchainToken.js | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index f675a1e4..313d9f6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.0.0", "license": "MIT", "dependencies": { - "@axelar-network/axelar-cgp-solidity": "6.3.1", + "@axelar-network/axelar-cgp-solidity": "6.4.0", "@axelar-network/axelar-gmp-sdk-solidity": "6.0.0" }, "devDependencies": { @@ -50,20 +50,20 @@ "dev": true }, "node_modules/@axelar-network/axelar-cgp-solidity": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@axelar-network/axelar-cgp-solidity/-/axelar-cgp-solidity-6.3.1.tgz", - "integrity": "sha512-RJmcOQbj2VhQb8uqBtu0beNj4MKRVjiYj74wXu6QI/a4bJ5EwwZK3+uCbTVNM9Qc7LqJqObhtGQfKUnAXEFCHA==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@axelar-network/axelar-cgp-solidity/-/axelar-cgp-solidity-6.4.0.tgz", + "integrity": "sha512-Xnw5xi234B1cmTCzgudV8zq+DDjJ1d1U362CM0vKH1FWmZprKIdqgmOYkiRyu+QiVhnznKiBURiSEHVrNjtYpw==", "dependencies": { - "@axelar-network/axelar-gmp-sdk-solidity": "5.8.0" + "@axelar-network/axelar-gmp-sdk-solidity": "5.10.0" }, "engines": { "node": ">=18" } }, "node_modules/@axelar-network/axelar-cgp-solidity/node_modules/@axelar-network/axelar-gmp-sdk-solidity": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-5.8.0.tgz", - "integrity": "sha512-ThiCWK7lhwmsipgjKkw8c0z0ubB9toRMV9X0tRVOXHHSknKp5DCFfatbCwjpSC5GZRa+61ciTSqJNtCc7j9YoQ==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-5.10.0.tgz", + "integrity": "sha512-s8SImALvYB+5AeiT3tbfWNBI2Mhqw1x91i/zM3DNpVUCnAR2HKtsB9T84KnUn/OJjOVgb4h0lv7q9smeYniRPw==", "engines": { "node": ">=18" } diff --git a/package.json b/package.json index 6b6f2afb..18e2069a 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "node": ">=18" }, "dependencies": { - "@axelar-network/axelar-cgp-solidity": "6.3.1", + "@axelar-network/axelar-cgp-solidity": "6.4.0", "@axelar-network/axelar-gmp-sdk-solidity": "6.0.0" }, "devDependencies": { diff --git a/test/InterchainToken.js b/test/InterchainToken.js index a7ff687a..62303f04 100644 --- a/test/InterchainToken.js +++ b/test/InterchainToken.js @@ -147,7 +147,7 @@ describe('InterchainToken', () => { const contractBytecodeHash = keccak256(contractBytecode); const expected = { - london: '0xa01cf28b0b6ce6dc3b466e995585d69486400d671fce0ea8d06beba583e6f3bb', + london: '0x75a10f371014f97a894e69395422a36cc9e9961e32371c0213ed514702966b24', }[getEVMVersion()]; expect(contractBytecodeHash).to.be.equal(expected); From a0223dda7cf7d3146ddcd50ccc3eb9c943519533 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 17 Oct 2024 11:08:59 -0700 Subject: [PATCH 23/25] move _setup function after constructor --- contracts/InterchainTokenFactory.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index 861a8997..fa07b360 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -42,6 +42,8 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M gateway = IAxelarGatewayWithToken(address(interchainTokenService.gateway())); } + function _setup(bytes calldata data) internal override {} + /** * @notice Getter for the contract id. * @return bytes32 The contract id of this contract. @@ -50,8 +52,6 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M return CONTRACT_ID; } - function _setup(bytes calldata params) internal override {} - /** * @notice Calculates the salt for an interchain token. * @param chainNameHash_ The hash of the chain name. From 2996eacab9ee72222feb76f2360cbfe3df3170a0 Mon Sep 17 00:00:00 2001 From: ahramy Date: Fri, 25 Oct 2024 11:41:07 -0700 Subject: [PATCH 24/25] Update InterchainToken.js --- test/InterchainToken.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/InterchainToken.js b/test/InterchainToken.js index 62303f04..a7ff687a 100644 --- a/test/InterchainToken.js +++ b/test/InterchainToken.js @@ -147,7 +147,7 @@ describe('InterchainToken', () => { const contractBytecodeHash = keccak256(contractBytecode); const expected = { - london: '0x75a10f371014f97a894e69395422a36cc9e9961e32371c0213ed514702966b24', + london: '0xa01cf28b0b6ce6dc3b466e995585d69486400d671fce0ea8d06beba583e6f3bb', }[getEVMVersion()]; expect(contractBytecodeHash).to.be.equal(expected); From 645186b590c7b415a4b738c8a317441ee8912c10 Mon Sep 17 00:00:00 2001 From: ahramy Date: Fri, 25 Oct 2024 14:06:35 -0700 Subject: [PATCH 25/25] updated gmp-sdk version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 438544a5..3b713616 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@axelar-network/axelar-cgp-solidity": "6.4.0", - "@axelar-network/axelar-gmp-sdk-solidity": "6.0.0" + "@axelar-network/axelar-gmp-sdk-solidity": "6.0.1" }, "devDependencies": { "@axelar-network/axelar-chains-config": "^1.2.0", @@ -80,9 +80,9 @@ } }, "node_modules/@axelar-network/axelar-gmp-sdk-solidity": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-6.0.0.tgz", - "integrity": "sha512-skmHwbvYOkyuIrL5twVDlRNbyDAWQXcPGGufSMhBZ125iy85TAti76EFayoyfFXvLsq3BnKE8D+D1iC2mXB5eA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@axelar-network/axelar-gmp-sdk-solidity/-/axelar-gmp-sdk-solidity-6.0.1.tgz", + "integrity": "sha512-hxLRvxrx7LjG8QqL5Myh4Fq1hGN4y64ZK6a0YtoIK44YXLloeWSzgDVn5C8E8FoQHOTYAE6RpSVbilDgss480Q==", "engines": { "node": ">=18" } diff --git a/package.json b/package.json index 1814bb61..bddef914 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "dependencies": { "@axelar-network/axelar-cgp-solidity": "6.4.0", - "@axelar-network/axelar-gmp-sdk-solidity": "6.0.0" + "@axelar-network/axelar-gmp-sdk-solidity": "6.0.1" }, "devDependencies": { "@axelar-network/axelar-chains-config": "^1.2.0",