From 53dd41433c3f1139120b3c5cc58a750e84a7686f Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Tue, 29 Oct 2024 01:59:03 -0400 Subject: [PATCH] refactor!: remove gateway token support (#289) --- contracts/InterchainTokenFactory.sol | 31 +- contracts/InterchainTokenService.sol | 203 ++---- contracts/TokenHandler.sol | 51 +- contracts/interfaces/IGatewayCaller.sol | 22 +- .../interfaces/IInterchainTokenFactory.sol | 16 - .../interfaces/IInterchainTokenService.sol | 4 +- contracts/interfaces/ITokenHandler.sol | 15 +- contracts/interfaces/ITokenManagerType.sol | 3 +- contracts/utils/GatewayCaller.sol | 53 -- scripts/deploy.js | 2 +- scripts/utils.js | 41 -- test/InterchainTokenFactory.js | 94 +-- test/InterchainTokenService.js | 577 +----------------- test/InterchainTokenServiceUpgradeFlow.js | 2 +- test/constants.js | 2 - 15 files changed, 83 insertions(+), 1033 deletions(-) diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index fa07b360..6d5a8c88 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -5,7 +5,6 @@ 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 { 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,12 +20,10 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M IInterchainTokenService public immutable interchainTokenService; bytes32 public immutable chainNameHash; - IAxelarGatewayWithToken public immutable gateway; bytes32 private constant CONTRACT_ID = keccak256('interchain-token-factory'); bytes32 internal constant PREFIX_CANONICAL_TOKEN_SALT = keccak256('canonical-token-salt'); bytes32 internal constant PREFIX_INTERCHAIN_TOKEN_SALT = keccak256('interchain-token-salt'); - bytes32 internal constant PREFIX_GATEWAY_TOKEN_SALT = keccak256('gateway-token-salt'); address private constant TOKEN_FACTORY_DEPLOYER = address(0); /** @@ -39,7 +36,6 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M interchainTokenService = IInterchainTokenService(interchainTokenService_); chainNameHash = interchainTokenService.chainNameHash(); - gateway = IAxelarGatewayWithToken(address(interchainTokenService.gateway())); } function _setup(bytes calldata data) internal override {} @@ -73,15 +69,6 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M salt = keccak256(abi.encode(PREFIX_CANONICAL_TOKEN_SALT, chainNameHash_, tokenAddress)); } - /** - * @notice Calculates the salt for a gateway interchain token. - * @param tokenIdentifier A unique identifier to generate the salt. - * @return salt The calculated salt for the interchain token. - */ - function gatewayTokenSalt(bytes32 tokenIdentifier) public pure returns (bytes32 salt) { - salt = keccak256(abi.encode(PREFIX_GATEWAY_TOKEN_SALT, tokenIdentifier)); - } - /** * @notice Computes the ID for an interchain token based on the deployer and a salt. * @param deployer The address that deployed the interchain token. @@ -297,8 +284,9 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M string memory tokenName = token.name(); string memory tokenSymbol = token.symbol(); uint8 tokenDecimals = token.decimals(); + bytes memory minter = ''; // No additional minter is set on a canonical token deployment - tokenId = _deployInterchainToken(salt, destinationChain, tokenName, tokenSymbol, tokenDecimals, '', gasValue); + tokenId = _deployInterchainToken(salt, destinationChain, tokenName, tokenSymbol, tokenDecimals, minter, gasValue); } /** @@ -322,19 +310,4 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M tokenId = deployRemoteCanonicalInterchainToken(originalTokenAddress, destinationChain, gasValue); } - - /** - * @notice Register 'canonical' gateway tokens. The same salt needs to be used for the same gateway token on every chain. - * @param tokenIdentifier A gateway token identifier to be used for the token registration. Should be the same for all chains. - * @param symbol The symbol of the token to register. - */ - function registerGatewayToken(bytes32 tokenIdentifier, string calldata symbol) external onlyOwner returns (bytes32 tokenId) { - address tokenAddress = gateway.tokenAddresses(symbol); - if (tokenAddress == address(0)) revert NotGatewayToken(symbol); - - bytes memory params = abi.encode('', tokenAddress); - bytes32 salt = gatewayTokenSalt(tokenIdentifier); - - tokenId = interchainTokenService.deployTokenManager(salt, '', TokenManagerType.GATEWAY, params, 0); - } } diff --git a/contracts/InterchainTokenService.sol b/contracts/InterchainTokenService.sol index ec4d5d02..a19e1d5b 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -5,7 +5,6 @@ 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 { 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'; @@ -475,22 +474,11 @@ contract InterchainTokenService is bytes calldata metadata, uint256 gasValue ) external payable whenNotPaused { - string memory symbol; - (amount, symbol) = _takeToken(tokenId, msg.sender, amount, false); + amount = _takeToken(tokenId, msg.sender, amount, false); (IGatewayCaller.MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata); - _transmitInterchainTransfer( - tokenId, - msg.sender, - destinationChain, - destinationAddress, - amount, - metadataVersion, - data, - symbol, - gasValue - ); + _transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadataVersion, data, gasValue); } /** @@ -510,8 +498,7 @@ contract InterchainTokenService is uint256 gasValue ) external payable whenNotPaused { if (data.length == 0) revert EmptyData(); - string memory symbol; - (amount, symbol) = _takeToken(tokenId, msg.sender, amount, false); + amount = _takeToken(tokenId, msg.sender, amount, false); _transmitInterchainTransfer( tokenId, @@ -521,7 +508,6 @@ contract InterchainTokenService is amount, IGatewayCaller.MetadataVersion.CONTRACT_CALL, data, - symbol, gasValue ); } @@ -548,22 +534,11 @@ contract InterchainTokenService is uint256 amount, bytes calldata metadata ) external payable whenNotPaused { - string memory symbol; - (amount, symbol) = _takeToken(tokenId, sourceAddress, amount, true); + amount = _takeToken(tokenId, sourceAddress, amount, true); (IGatewayCaller.MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata); - _transmitInterchainTransfer( - tokenId, - sourceAddress, - destinationChain, - destinationAddress, - amount, - metadataVersion, - data, - symbol, - msg.value - ); + _transmitInterchainTransfer(tokenId, sourceAddress, destinationChain, destinationAddress, amount, metadataVersion, data, msg.value); } /*************\ @@ -659,74 +634,44 @@ contract InterchainTokenService is } /** - * @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. - * @param sourceChain The source chain. - * @param sourceAddress The source address on the source chain. - * @param payload The payload sent with the call. - * @param symbol The symbol symbol for the call. - * @param amount The amount for the call. - * @return address The token address. - * @return uint256 The value the call is worth. + * @notice Call with gateway tokens are not supported. */ function contractCallWithTokenValue( - string calldata sourceChain, - string calldata sourceAddress, - bytes calldata payload, - string calldata symbol, - uint256 amount - ) public view virtual onlyRemoteService(sourceChain, sourceAddress) whenNotPaused returns (address, uint256) { - _checkPayloadAgainstGatewayData(payload, symbol, amount); - return _contractCallValue(payload); + string calldata /* sourceChain */, + string calldata /* sourceAddress */, + bytes calldata /* payload */, + string calldata /* symbol */, + uint256 /* amount */ + ) public pure override returns (address, uint256) { + revert NotSupported(); } /** - * @notice Express executes with a gateway token 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. - * @param tokenSymbol The symbol symbol for the call. - * @param amount The amount for the call. + * @notice Call with gateway tokens are not supported. */ function expressExecuteWithToken( - bytes32 commandId, - string calldata sourceChain, - string calldata sourceAddress, - bytes calldata payload, - string calldata tokenSymbol, - uint256 amount + bytes32 /* commandId */, + string calldata /* sourceChain */, + string calldata /* sourceAddress */, + bytes calldata /* payload */, + string calldata /* tokenSymbol */, + uint256 /* amount */ ) external payable { - _checkPayloadAgainstGatewayData(payload, tokenSymbol, amount); - // It should be ok to ignore the symbol and amount since this info exists on the payload. - 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); + revert NotSupported(); } /** - * @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. - * @param payload The payload for the call contract with token. - * @param tokenSymbol The tokenSymbol for the call contract with token. - * @param amount The amount for the call contract with token. + * @notice Call with gateway tokens are not supported. */ - function _checkPayloadAgainstGatewayData(bytes memory payload, string calldata tokenSymbol, uint256 amount) internal view { - // The same payload is decoded in both _checkPayloadAgainstGatewayData and _contractCallValue using different parameters. - // This is intentional, as using `uint256` instead of `bytes` improves gas efficiency without any functional difference. - (, bytes32 tokenId, , , uint256 amountInPayload) = abi.decode(payload, (uint256, bytes32, uint256, uint256, uint256)); - - if (validTokenAddress(tokenId) != gatewayWithToken().tokenAddresses(tokenSymbol) || amount != amountInPayload) - revert InvalidGatewayTokenTransfer(tokenId, payload, tokenSymbol, amount); + function executeWithToken( + bytes32 /* commandId */, + string calldata /* sourceChain */, + string calldata /* sourceAddress */, + bytes calldata /* payload */, + string calldata /* tokenSymbol */, + uint256 /* amount */ + ) external pure { + revert NotSupported(); } /** @@ -756,11 +701,9 @@ contract InterchainTokenService is destinationAddress = destinationAddressBytes.toAddress(); } - // Return token to the existing express caller + // Return token to the express executor if (expressExecutor != address(0)) { - // slither-disable-next-line unused-return _giveToken(tokenId, expressExecutor, amount); - return; } @@ -855,40 +798,6 @@ contract InterchainTokenService is if (!success) revert GatewayCallFailed(returnData); } - /** - * @notice Calls a contract on a specific destination chain with the given payload and gateway token - * @param destinationChain The target chain where the contract will be called. - * @param payload The data payload for the transaction. - * @param gasValue The amount of gas to be paid for the transaction. - */ - function _callContractWithToken( - string memory destinationChain, - bytes memory payload, - string memory symbol, - uint256 amount, - IGatewayCaller.MetadataVersion metadataVersion, - uint256 gasValue - ) internal { - string memory destinationAddress; - - (destinationChain, destinationAddress, payload) = _getCallParams(destinationChain, payload); - - (bool success, bytes memory returnData) = gatewayCaller.delegatecall( - abi.encodeWithSelector( - IGatewayCaller.callContractWithToken.selector, - destinationChain, - destinationAddress, - payload, - symbol, - amount, - metadataVersion, - gasValue - ) - ); - - if (!success) revert GatewayCallFailed(returnData); - } - /** * @dev Get the params for the cross-chain message, taking routing via ITS Hub into account. */ @@ -938,35 +847,6 @@ contract InterchainTokenService is } } - function _executeWithToken( - bytes32 commandId, - string calldata sourceChain, - string calldata sourceAddress, - bytes memory payload, - string calldata tokenSymbol, - uint256 amount - ) internal { - bytes32 payloadHash = keccak256(payload); - - if (!gatewayWithToken().validateContractCallAndMint(commandId, sourceChain, sourceAddress, payloadHash, tokenSymbol, amount)) - revert NotApprovedByGateway(); - - uint256 messageType; - string memory originalSourceChain; - (messageType, originalSourceChain, payload) = _getExecuteParams(sourceChain, payload); - - if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) { - revert InvalidMessageType(messageType); - } - - _checkPayloadAgainstGatewayData(payload, tokenSymbol, amount); - - // slither-disable-next-line reentrancy-events - address expressExecutor = _getExpressExecutorAndEmitEvent(commandId, sourceChain, sourceAddress, payloadHash); - - _processInterchainTransferPayload(commandId, expressExecutor, originalSourceChain, payload); - } - function _getMessageType(bytes memory payload) internal pure returns (uint256 messageType) { if (payload.length < 32) revert InvalidPayload(); @@ -1162,6 +1042,7 @@ contract InterchainTokenService is * @param amount The amount of tokens to send. * @param metadataVersion The version of the metadata. * @param data The data to be passed with the token transfer. + * @param gasValue The amount of gas to be paid for the transaction. */ function _transmitInterchainTransfer( bytes32 tokenId, @@ -1171,7 +1052,6 @@ contract InterchainTokenService is uint256 amount, IGatewayCaller.MetadataVersion metadataVersion, bytes memory data, - string memory symbol, uint256 gasValue ) internal { if (amount == 0) revert ZeroAmount(); @@ -1194,24 +1074,21 @@ contract InterchainTokenService is amount, data ); - if (bytes(symbol).length > 0) { - _callContractWithToken(destinationChain, payload, symbol, amount, metadataVersion, gasValue); - } else { - _callContract(destinationChain, payload, metadataVersion, gasValue); - } + + _callContract(destinationChain, payload, metadataVersion, gasValue); } /** * @dev Takes token from a sender via the token service. `tokenOnly` indicates if the caller should be restricted to the token only. */ - function _takeToken(bytes32 tokenId, address from, uint256 amount, bool tokenOnly) internal returns (uint256, string memory symbol) { + function _takeToken(bytes32 tokenId, address from, uint256 amount, bool tokenOnly) internal returns (uint256) { (bool success, bytes memory data) = tokenHandler.delegatecall( abi.encodeWithSelector(ITokenHandler.takeToken.selector, tokenId, tokenOnly, from, amount) ); if (!success) revert TakeTokenFailed(data); - (amount, symbol) = abi.decode(data, (uint256, string)); + amount = abi.decode(data, (uint256)); - return (amount, symbol); + return amount; } /** @@ -1255,8 +1132,4 @@ contract InterchainTokenService is emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); } } - - function gatewayWithToken() internal view returns (IAxelarGatewayWithToken) { - return IAxelarGatewayWithToken(address(gateway)); - } } diff --git a/contracts/TokenHandler.sol b/contracts/TokenHandler.sol index 14fac5a9..18cde203 100644 --- a/contracts/TokenHandler.sol +++ b/contracts/TokenHandler.sol @@ -13,7 +13,6 @@ import { ITokenManager } from './interfaces/ITokenManager.sol'; import { ITokenManagerProxy } from './interfaces/ITokenManagerProxy.sol'; import { IERC20MintableBurnable } from './interfaces/IERC20MintableBurnable.sol'; import { IERC20BurnableFrom } from './interfaces/IERC20BurnableFrom.sol'; -import { IERC20Named } from './interfaces/IERC20Named.sol'; /** * @title TokenHandler @@ -24,15 +23,6 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea using SafeTokenCall for IERC20; using SafeTokenTransfer for IERC20; - address public immutable gateway; - - uint256 internal constant UINT256_MAX = type(uint256).max; - - constructor(address gateway_) { - if (gateway_ == address(0)) revert AddressZero(); - gateway = gateway_; - } - /** * @notice This function gives token to a specified address from the token manager. * @param tokenId The token id of the tokenManager. @@ -70,11 +60,6 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea return (amount, tokenAddress); } - if (tokenManagerType == uint256(TokenManagerType.GATEWAY)) { - _transferToken(tokenAddress, to, amount); - return (amount, tokenAddress); - } - revert UnsupportedTokenManagerType(tokenManagerType); } @@ -85,15 +70,9 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea * @param from The address to take tokens from. * @param amount The amount of token to take. * @return uint256 The amount of token actually taken, which could be different for certain token type. - * @return symbol The symbol for the token, if not empty the token is a gateway token and a callContractWith token has to be made. */ // slither-disable-next-line locked-ether - function takeToken( - bytes32 tokenId, - bool tokenOnly, - address from, - uint256 amount - ) external payable returns (uint256, string memory symbol) { + function takeToken(bytes32 tokenId, bool tokenOnly, address from, uint256 amount) external payable returns (uint256) { address tokenManager = _create3Address(tokenId); (uint256 tokenManagerType, address tokenAddress) = ITokenManagerProxy(tokenManager).getImplementationTypeAndTokenAddress(); @@ -109,9 +88,6 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea _transferTokenFrom(tokenAddress, from, tokenManager, amount); } else if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) { amount = _transferTokenFromWithFee(tokenAddress, from, tokenManager, amount); - } else if (tokenManagerType == uint256(TokenManagerType.GATEWAY)) { - symbol = IERC20Named(tokenAddress).symbol(); - _transferTokenFrom(tokenAddress, from, address(this), amount); } else { revert UnsupportedTokenManagerType(tokenManagerType); } @@ -119,7 +95,7 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea /// @dev Track the flow amount being sent out as a message ITokenManager(tokenManager).addFlowOut(amount); - return (amount, symbol); + return amount; } /** @@ -140,8 +116,7 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea tokenManagerType == uint256(TokenManagerType.NATIVE_INTERCHAIN_TOKEN) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.MINT_BURN) || - tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM) || - tokenManagerType == uint256(TokenManagerType.GATEWAY) + tokenManagerType == uint256(TokenManagerType.MINT_BURN_FROM) ) { _transferTokenFrom(tokenAddress, from, to, amount); return (amount, tokenAddress); @@ -162,16 +137,10 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea */ // slither-disable-next-line locked-ether function postTokenManagerDeploy(uint256 tokenManagerType, address tokenManager) external payable { + // For lock/unlock token managers, the ITS contract needs an approval from the token manager to transfer tokens on its behalf if (tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK) || tokenManagerType == uint256(TokenManagerType.LOCK_UNLOCK_FEE)) { ITokenManager(tokenManager).approveService(); } - - // Approve the gateway here. One-time infinite approval works for gateway wrapped tokens, and for most origin tokens. - // Approval can be refreshed in the future if needed for certain tokens via an upgrade, but realistically should never be exhausted. - if (tokenManagerType == uint256(TokenManagerType.GATEWAY)) { - address token = ITokenManager(tokenManager).tokenAddress(); - _approveGateway(token, UINT256_MAX); - } } function _transferTokenFrom(address tokenAddress, address from, address to, uint256 amount) internal { @@ -179,11 +148,6 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea IERC20(tokenAddress).safeTransferFrom(from, to, amount); } - function _transferToken(address tokenAddress, address to, uint256 amount) internal { - // slither-disable-next-line arbitrary-send-erc20 - IERC20(tokenAddress).safeTransfer(to, amount); - } - function _transferTokenFromWithFee( address tokenAddress, address from, @@ -221,11 +185,4 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea function _burnTokenFrom(address tokenAddress, address from, uint256 amount) internal { IERC20(tokenAddress).safeCall(abi.encodeWithSelector(IERC20BurnableFrom.burnFrom.selector, from, amount)); } - - function _approveGateway(address tokenAddress, uint256 amount) internal { - uint256 allowance = IERC20(tokenAddress).allowance(address(this), gateway); - if (allowance == 0) { - IERC20(tokenAddress).safeCall(abi.encodeWithSelector(IERC20.approve.selector, gateway, amount)); - } - } } diff --git a/contracts/interfaces/IGatewayCaller.sol b/contracts/interfaces/IGatewayCaller.sol index 8093720d..1670cc82 100644 --- a/contracts/interfaces/IGatewayCaller.sol +++ b/contracts/interfaces/IGatewayCaller.sol @@ -21,7 +21,7 @@ interface IGatewayCaller { error InvalidMetadataVersion(uint32 metadataVersion); /** - * @dev Calls a contract on a specific destination chain with the given payload + * @notice Call the Axelar gateway to send a payload to a destination contract on a specific destination chain * @param destinationChain The target chain where the contract will be called * @param destinationAddress The address of the contract to be called on the destination chain * @param payload The data payload for the transaction @@ -35,24 +35,4 @@ interface IGatewayCaller { MetadataVersion metadataVersion, uint256 gasValue ) external payable; - - /** - * @dev Calls a contract on a specific destination chain with the given payload and token - * @param destinationChain The target chain where the contract will be called - * @param destinationAddress The address of the contract to be called on the destination chain - * @param payload The data payload for the transaction - * @param symbol The symbol of the token to be sent - * @param amount The amount of tokens to be sent - * @param metadataVersion The version of metadata to be used - * @param gasValue The amount of gas to be paid for the cross-chain message. If this is 0, then gas payment is skipped. `msg.value` must be at least gasValue. - */ - function callContractWithToken( - string calldata destinationChain, - string calldata destinationAddress, - bytes calldata payload, - string calldata symbol, - uint256 amount, - MetadataVersion metadataVersion, - uint256 gasValue - ) external payable; } diff --git a/contracts/interfaces/IInterchainTokenFactory.sol b/contracts/interfaces/IInterchainTokenFactory.sol index 92c829a6..0dbdb311 100644 --- a/contracts/interfaces/IInterchainTokenFactory.sol +++ b/contracts/interfaces/IInterchainTokenFactory.sol @@ -17,9 +17,7 @@ interface IInterchainTokenFactory is IUpgradable, IMulticall { error InvalidMinter(address minter); error NotMinter(address minter); error NotOperator(address operator); - error GatewayToken(address tokenAddress); error NotServiceOwner(address sender); - error NotGatewayToken(string symbol); error NotSupported(); /** @@ -163,18 +161,4 @@ interface IInterchainTokenFactory is IUpgradable, IMulticall { string calldata destinationChain, uint256 gasValue ) external payable returns (bytes32 tokenId); - - /** - * @notice Calculates the salt for a gateway interchain token. - * @param tokenIdentifier A unique identifier to generate the salt. - * @return salt The calculated salt for the interchain token. - */ - function gatewayTokenSalt(bytes32 tokenIdentifier) external pure returns (bytes32 salt); - - /** - * @notice Register 'canonical' gateway tokens. The same salt needs to be used for the same gateway token on every chain. - * @param tokenIdentifier A gateway token identifier to be used for the token registration. Should be the same for all chains. - * @param symbol The symbol of the token to register. - */ - function registerGatewayToken(bytes32 tokenIdentifier, string calldata symbol) external returns (bytes32 tokenId); } diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index f9d5d9cc..451236a2 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -34,12 +34,10 @@ interface IInterchainTokenService is error TokenManagerDoesNotExist(bytes32 tokenId); error ExecuteWithInterchainTokenFailed(address contractAddress); error ExpressExecuteWithInterchainTokenFailed(address contractAddress); - error GatewayToken(); error TokenManagerDeploymentFailed(bytes error); error InterchainTokenDeploymentFailed(bytes error); error InvalidMessageType(uint256 messageType); error InvalidMetadataVersion(uint32 version); - error ExecuteWithTokenNotSupported(); error InvalidExpressMessageType(uint256 messageType); error TakeTokenFailed(bytes data); error GiveTokenFailed(bytes data); @@ -49,9 +47,9 @@ interface IInterchainTokenService is error ZeroAmount(); error CannotDeploy(TokenManagerType); error CannotDeployRemotelyToSelf(); - error InvalidGatewayTokenTransfer(bytes32 tokenId, bytes payload, string tokenSymbol, uint256 amount); error InvalidPayload(); error GatewayCallFailed(bytes data); + error NotSupported(); event InterchainTransfer( bytes32 indexed tokenId, diff --git a/contracts/interfaces/ITokenHandler.sol b/contracts/interfaces/ITokenHandler.sol index 992079c7..2b7f3f3e 100644 --- a/contracts/interfaces/ITokenHandler.sol +++ b/contracts/interfaces/ITokenHandler.sol @@ -8,15 +8,8 @@ pragma solidity ^0.8.0; */ interface ITokenHandler { error UnsupportedTokenManagerType(uint256 tokenManagerType); - error AddressZero(); error NotToken(address caller, address token); - /** - * @notice Returns the address of the axelar gateway on this chain. - * @return gateway_ The address of the axelar gateway contract. - */ - function gateway() external view returns (address gateway_); - /** * @notice This function gives token to a specified address from the token manager. * @param tokenId The token id of the tokenManager. @@ -34,15 +27,9 @@ interface ITokenHandler { * @param from The address to take tokens from. * @param amount The amount of token to take. * @return uint256 The amount of token actually taken, which could be different for certain token type. - * @return symbol The symbol for the token, if not empty the token is a gateway token and a callContractWith token has to be made. */ // slither-disable-next-line locked-ether - function takeToken( - bytes32 tokenId, - bool tokenOnly, - address from, - uint256 amount - ) external payable returns (uint256, string memory symbol); + function takeToken(bytes32 tokenId, bool tokenOnly, address from, uint256 amount) external payable returns (uint256); /** * @notice This function transfers token from and to a specified address. diff --git a/contracts/interfaces/ITokenManagerType.sol b/contracts/interfaces/ITokenManagerType.sol index ca545b5b..d03db6c7 100644 --- a/contracts/interfaces/ITokenManagerType.sol +++ b/contracts/interfaces/ITokenManagerType.sol @@ -12,7 +12,6 @@ interface ITokenManagerType { MINT_BURN_FROM, // The token will be minted/burned on transfers. The token needs to give mint permission to the token manager, but burning happens via an approval. LOCK_UNLOCK, // The token will be locked/unlocked at the token manager. LOCK_UNLOCK_FEE, // The token will be locked/unlocked at the token manager, which will account for any fee-on-transfer behaviour. - MINT_BURN, // The token will be minted/burned on transfers. The token needs to give mint and burn permission to the token manager. - GATEWAY // The token will be sent through the gateway via callContractWithToken + MINT_BURN // The token will be minted/burned on transfers. The token needs to give mint and burn permission to the token manager. } } diff --git a/contracts/utils/GatewayCaller.sol b/contracts/utils/GatewayCaller.sol index df81612c..62da09ad 100644 --- a/contracts/utils/GatewayCaller.sol +++ b/contracts/utils/GatewayCaller.sol @@ -4,7 +4,6 @@ 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 { IAxelarGatewayWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGatewayWithToken.sol'; import { IGatewayCaller } from '../interfaces/IGatewayCaller.sol'; /** @@ -68,56 +67,4 @@ contract GatewayCaller is IGatewayCaller { gateway.callContract(destinationChain, destinationAddress, payload); } - - /** - * @dev Calls a contract on a specific destination chain with the given payload and token - * @param destinationChain The target chain where the contract will be called - * @param destinationAddress The address of the contract to be called on the destination chain - * @param payload The data payload for the transaction - * @param symbol The symbol of the token to be sent - * @param amount The amount of tokens to be sent - * @param metadataVersion The version of metadata to be used - * @param gasValue The amount of gas to be paid for the cross-chain message. If this is 0, then gas payment is skipped. `msg.value` must be at least gasValue. - */ - function callContractWithToken( - string calldata destinationChain, - string calldata destinationAddress, - bytes calldata payload, - string calldata symbol, - uint256 amount, - MetadataVersion metadataVersion, - uint256 gasValue - ) external payable override { - if (gasValue > 0) { - if (metadataVersion == MetadataVersion.CONTRACT_CALL) { - // slither-disable-next-line arbitrary-send-eth - gasService.payNativeGasForContractCallWithToken{ value: gasValue }( - address(this), - destinationChain, - destinationAddress, - payload, - symbol, - amount, - // solhint-disable-next-line avoid-tx-origin - tx.origin - ); - } else if (metadataVersion == MetadataVersion.EXPRESS_CALL) { - // slither-disable-next-line arbitrary-send-eth - gasService.payNativeGasForExpressCallWithToken{ value: gasValue }( - address(this), - destinationChain, - destinationAddress, - payload, - symbol, - amount, - // solhint-disable-next-line avoid-tx-origin - tx.origin - ); - } else { - revert InvalidMetadataVersion(uint32(metadataVersion)); - } - } - - IAxelarGatewayWithToken(address(gateway)).callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount); - } } diff --git a/scripts/deploy.js b/scripts/deploy.js index 1a32e3f0..a1db9206 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -95,7 +95,7 @@ async function deployAll( const interchainToken = await deployContract(wallet, 'InterchainToken', [interchainTokenServiceAddress]); const interchainTokenDeployer = await deployContract(wallet, 'InterchainTokenDeployer', [interchainToken.address]); const tokenManager = await deployContract(wallet, 'TokenManager', [interchainTokenServiceAddress]); - const tokenHandler = await deployContract(wallet, 'TokenHandler', [gateway.address]); + const tokenHandler = await deployContract(wallet, 'TokenHandler', []); const gatewayCaller = await deployContract(wallet, 'GatewayCaller', [gateway.address, gasService.address]); const interchainTokenFactoryAddress = await getCreate3Address(create3Deployer.address, wallet, factoryDeploymentKey); diff --git a/scripts/utils.js b/scripts/utils.js index 7a512156..8fd9d8be 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -1,6 +1,4 @@ const { ethers } = require('hardhat'); -const { deployContract } = require('./deploy'); -const { AddressZero } = ethers.constants; const { defaultAbiCoder, keccak256 } = ethers.utils; function getRandomBytes32() { @@ -26,46 +24,7 @@ async function approveContractCall( return commandId; } -async function approveContractCallWithMint( - gateway, - sourceChain, - sourceAddress, - contractAddress, - payload, - symbol, - amount, - sourceTxHash = getRandomBytes32(), - sourceEventIndex = 0, - commandId = getRandomBytes32(), -) { - const params = defaultAbiCoder.encode( - ['string', 'string', 'address', 'bytes32', 'string', 'uint256', 'bytes32', 'uint256'], - [sourceChain, sourceAddress, contractAddress, keccak256(payload), symbol, amount, sourceTxHash, sourceEventIndex], - ); - await gateway.approveContractCallWithMint(params, commandId).then((tx) => tx.wait); - - return commandId; -} - -async function deployGatewayToken(gateway, tokenName, tokenSymbol, tokenDecimals, walletForExternal) { - let tokenAddress = AddressZero; - - if (walletForExternal) { - const token = await deployContract(walletForExternal, 'GatewayToken', [tokenName, tokenSymbol, tokenDecimals]); - tokenAddress = token.address; - } - - const params = defaultAbiCoder.encode( - ['string', 'string', 'uint8', 'uint256', 'address', 'uint256'], - [tokenName, tokenSymbol, tokenDecimals, 0, tokenAddress, 0], - ); - const commandId = getRandomBytes32(); - await gateway.deployToken(params, commandId).then((tx) => tx.wait); -} - module.exports = { getRandomBytes32, approveContractCall, - approveContractCallWithMint, - deployGatewayToken, }; diff --git a/test/InterchainTokenFactory.js b/test/InterchainTokenFactory.js index 261a51c7..f201e7c7 100644 --- a/test/InterchainTokenFactory.js +++ b/test/InterchainTokenFactory.js @@ -7,7 +7,7 @@ const { getContractAt, Wallet, constants: { AddressZero }, - utils: { defaultAbiCoder, keccak256, toUtf8Bytes, id }, + utils: { defaultAbiCoder, keccak256, toUtf8Bytes }, } = ethers; const { deployAll, deployContract } = require('../scripts/deploy'); const { getRandomBytes32, expectRevert } = require('./utils'); @@ -15,7 +15,6 @@ const { MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, NATIVE_INTERCHAIN_TOKEN, LOCK_UNLOCK, - GATEWAY, MINTER_ROLE, OPERATOR_ROLE, FLOW_LIMITER_ROLE, @@ -155,97 +154,6 @@ describe('InterchainTokenFactory', () => { }); }); - describe('Gateway Interchain Token Factory', async () => { - let token, tokenId, tokenManagerAddress, symbol; - const tokenCap = BigInt(1e18); - - async function deployToken(salt, lockUnlock = true) { - let tokenAddress = AddressZero; - - if (lockUnlock) { - token = await deployContract(wallet, 'TestInterchainTokenStandard', [ - name, - symbol, - decimals, - service.address, - getRandomBytes32(), - ]); - tokenAddress = token.address; - } - - const params = defaultAbiCoder.encode( - ['string', 'string', 'uint8', 'uint256', 'address', 'uint256'], - [name, symbol, decimals, 0, tokenAddress, 0], - ); - - await gateway.deployToken(params, getRandomBytes32()).then((tx) => tx.wait); - - const deploySalt = keccak256(defaultAbiCoder.encode(['bytes32', 'bytes32'], [id('gateway-token-salt'), salt])); - tokenId = await service.interchainTokenId(AddressZero, deploySalt); - tokenManagerAddress = await service.tokenManagerAddress(tokenId); - - if (lockUnlock) { - await token.mint(wallet.address, tokenCap).then((tx) => tx.wait); - await token.setTokenId(tokenId).then((tx) => tx.wait); - } else { - tokenAddress = await gateway.tokenAddresses(symbol); - token = await getContractAt('IERC20', tokenAddress); - await gateway - .mintToken( - defaultAbiCoder.encode(['string', 'address', 'uint256'], [symbol, wallet.address, tokenCap]), - getRandomBytes32(), - ) - .then((tx) => tx.wait); - } - } - - it('Should register a token lock/unlock gateway token', async () => { - const salt = getRandomBytes32(); - symbol = 'TT0'; - await deployToken(salt, true); - const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); - - await expect(tokenFactory.registerGatewayToken(salt, symbol)) - .to.emit(service, 'TokenManagerDeployed') - .withArgs(tokenId, tokenManagerAddress, GATEWAY, params); - }); - - it('Should register a token mint/burn gateway token', async () => { - const salt = getRandomBytes32(); - symbol = 'TT1'; - await deployToken(salt, false); - const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); - - await expect(tokenFactory.registerGatewayToken(salt, symbol)) - .to.emit(service, 'TokenManagerDeployed') - .withArgs(tokenId, tokenManagerAddress, GATEWAY, params); - }); - - it('Should revert when trying to register a gateway token from non-owner address', async () => { - const salt = getRandomBytes32(); - const symbol = 'TT2'; - - await expectRevert( - (gasOptions) => tokenFactory.connect(otherWallet).registerGatewayToken(salt, symbol, gasOptions), - tokenFactory, - 'NotOwner', - [], - ); - }); - - it('Should revert when trying to register a gateway token that does not exist', async () => { - const salt = getRandomBytes32(); - const symbol = 'TT2'; - - await expectRevert( - (gasOptions) => tokenFactory.registerGatewayToken(salt, symbol, gasOptions), - tokenFactory, - 'NotGatewayToken', - [symbol], - ); - }); - }); - describe('Interchain Token Factory', async () => { let tokenId; const mintAmount = 1234; diff --git a/test/InterchainTokenService.js b/test/InterchainTokenService.js index 28cdb142..fb492039 100644 --- a/test/InterchainTokenService.js +++ b/test/InterchainTokenService.js @@ -11,7 +11,7 @@ const { } = ethers; const Create3Deployer = require('@axelar-network/axelar-gmp-sdk-solidity/artifacts/contracts/deploy/Create3Deployer.sol/Create3Deployer.json'); const { getCreate3Address } = require('@axelar-network/axelar-gmp-sdk-solidity'); -const { approveContractCall, approveContractCallWithMint } = require('../scripts/utils'); +const { approveContractCall } = require('../scripts/utils'); const { getRandomBytes32, getRandomInt, expectRevert, gasReporter, getEVMVersion } = require('./utils'); const { deployAll, deployContract, deployInterchainTokenService } = require('../scripts/deploy'); const { @@ -25,7 +25,6 @@ const { LOCK_UNLOCK, LOCK_UNLOCK_FEE_ON_TRANSFER, MINT_BURN, - GATEWAY, OPERATOR_ROLE, FLOW_LIMITER_ROLE, ITS_HUB_CHAIN_NAME, @@ -80,36 +79,6 @@ describe('Interchain Token Service', () => { return [token, tokenManager, tokenId]; } - async function deployNewGateway(service, tokenName, tokenSymbol, tokenDecimals, mintAmount = 0, skipApprove = false) { - const salt = getRandomBytes32(); - const tokenId = await service.interchainTokenId(wallet.address, salt); - const tokenManager = await getContractAt('TokenManager', await service.tokenManagerAddress(tokenId), wallet); - - const token = await deployContract(wallet, 'TestInterchainTokenStandard', [ - tokenName, - tokenSymbol, - tokenDecimals, - service.address, - tokenId, - ]); - let params = defaultAbiCoder.encode( - ['string', 'string', 'uint8', 'uint256', 'address', 'uint256'], - [tokenName, tokenSymbol, tokenDecimals, 0, token.address, 0], - ); - await gateway.deployToken(params, getRandomBytes32()).then((tx) => tx.wait); - - params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, token.address]); - - await service.deployTokenManager(salt, '', GATEWAY, params, 0).then((tx) => tx.wait); - - if (mintAmount > 0) { - await token.mint(wallet.address, mintAmount).then((tx) => tx.wait); - if (!skipApprove) await token.approve(service.address, mintAmount).then((tx) => tx.wait); - } - - return [token, tokenManager, tokenId]; - } - async function deployNewLockUnlockFee( service, tokenName, @@ -193,7 +162,6 @@ describe('Interchain Token Service', () => { }; deployFunctions.lockUnlock = deployNewLockUnlock; - deployFunctions.gateway = deployNewGateway; deployFunctions.lockUnlockFee = deployNewLockUnlockFee; deployFunctions.mintBurn = makeDeployNewMintBurn(MINT_BURN); deployFunctions.mintBurnFrom = makeDeployNewMintBurn(MINT_BURN_FROM); @@ -243,14 +211,6 @@ describe('Interchain Token Service', () => { ]); }); - it('Should revert on token handler deployment with invalid gateway address', async () => { - await expectRevert( - (gasOptions) => deployContract(wallet, 'TokenHandler', [AddressZero, gasOptions]), - tokenHandler, - 'AddressZero', - ); - }); - it('Should test setup revert cases', async () => { const operator = wallet.address; const trustedChainNames = ['ChainA', 'ChainB']; @@ -892,7 +852,7 @@ describe('Interchain Token Service', () => { ); }); - it('Should deploy a lock/unlock token manager', async () => { + it('Should deploy a lock_unlock token manager', async () => { const tokenManagerAddress = await service.tokenManagerAddress(tokenId); const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, token.address]); @@ -947,7 +907,7 @@ describe('Interchain Token Service', () => { ); }); - it('Should deploy a mint/burn token manager', async () => { + it('Should deploy a mint_burn token manager', async () => { const salt = getRandomBytes32(); const tokenId = await service.interchainTokenId(wallet.address, salt); const tokenManagerAddress = await service.tokenManagerAddress(tokenId); @@ -982,7 +942,7 @@ describe('Interchain Token Service', () => { expect(tokenAddressFromProxy).to.eq(token.address); }); - it('Should deploy a mint/burn_from token manager', async () => { + it('Should deploy a mint_burn_from token manager', async () => { const salt = getRandomBytes32(); const tokenId = await service.interchainTokenId(wallet.address, salt); const tokenManagerAddress = await service.tokenManagerAddress(tokenId); @@ -1019,7 +979,7 @@ describe('Interchain Token Service', () => { expect(tokenAddressFromProxy).to.eq(token.address); }); - it('Should deploy a lock/unlock with fee on transfer token manager', async () => { + it('Should deploy a lock_unlock_with_fee token manager', async () => { const salt = getRandomBytes32(); const tokenId = await service.interchainTokenId(wallet.address, salt); const tokenManagerAddress = await service.tokenManagerAddress(tokenId); @@ -1065,43 +1025,6 @@ describe('Interchain Token Service', () => { await service.setPauseStatus(false).then((tx) => tx.wait); }); - - it('Should not approve on the second token manager gateway deployment', async () => { - const name = 'Gateway Token Approval'; - const symbol = 'GTA'; - const decimals = 18; - const [token] = await deployFunctions.gateway(service, name, symbol, decimals); - - const salt = getRandomBytes32(); - const tokenId = await service.interchainTokenId(wallet.address, salt); - const tokenManagerAddress = await service.tokenManagerAddress(tokenId); - - const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, token.address]); - - const tx = service.deployTokenManager(salt, '', GATEWAY, params, 0); - const expectedTokenManagerAddress = await service.tokenManagerAddress(tokenId); - await expect(tx) - .to.emit(service, 'TokenManagerDeployed') - .withArgs(tokenId, expectedTokenManagerAddress, GATEWAY, params) - .and.to.not.emit(token, 'Approval'); - - expect(tokenManagerAddress).to.not.equal(AddressZero); - const tokenManager = await getContractAt('TokenManager', tokenManagerAddress, wallet); - - expect(await tokenManager.isOperator(wallet.address)).to.be.true; - expect(await tokenManager.isOperator(service.address)).to.be.true; - expect(await tokenManager.isFlowLimiter(wallet.address)).to.be.true; - expect(await tokenManager.isFlowLimiter(service.address)).to.be.true; - - const tokenAddress = await service.validTokenAddress(tokenId); - expect(tokenAddress).to.eq(token.address); - - const tokenManagerProxy = await getContractAt('TokenManagerProxy', tokenManagerAddress, wallet); - - const [implementation, tokenAddressFromProxy] = await tokenManagerProxy.getImplementationTypeAndTokenAddress(); - expect(implementation).to.eq(GATEWAY); - expect(tokenAddressFromProxy).to.eq(token.address); - }); }); describe('Initialize remote custom token manager deployment', () => { @@ -1428,8 +1351,8 @@ describe('Interchain Token Service', () => { ); }); - it('Should revert on initiating an interchain token transfer for gateway token when gateway call failed', async () => { - const [, , tokenId] = await deployFunctions.gateway(serviceTestGatewayCaller, 'Test Token gateway', 'TG1', 12, amount); + it('Should revert on initiating an interchain token transfer when gateway call failed', async () => { + const [, , tokenId] = await deployFunctions.mintBurn(serviceTestGatewayCaller, 'Test Token', 'TG1', 12, amount); const metadata = '0x00000000'; await expectRevert( (gasOptions) => @@ -1510,86 +1433,12 @@ describe('Interchain Token Service', () => { }); }); - describe('Execute with token checks', () => { - const sourceChain = 'source chain'; - let sourceAddress; - const amount = 1234; - let destAddress; - const tokenName = 'Token Name'; - const tokenSymbol = 'TS'; - const tokenDecimals = 16; - - before(async () => { - sourceAddress = service.address; - destAddress = wallet.address; - await deployFunctions.gateway(service, 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, - ); - + describe('Execute with token', () => { + it('should revert on execute with token', async () => { await expectRevert( - (gasOptions) => service.executeWithToken(commandId, sourceChain, wallet.address, '0x', tokenSymbol, amount, gasOptions), + (gasOptions) => service.executeWithToken(HashZero, 'sourceChain', wallet.address, '0x', 'TEST', 1, gasOptions), service, - 'NotRemoteService', - ); - }); - - it('Should revert on execute with token if the service is paused', async () => { - await service.setPauseStatus(true).then((tx) => tx.wait); - - const commandId = await approveContractCallWithMint( - gateway, - sourceChain, - sourceAddress, - service.address, - '0x', - tokenSymbol, - amount, - ); - - await expectRevert( - (gasOptions) => service.executeWithToken(commandId, sourceChain, sourceAddress, '0x', tokenSymbol, amount, gasOptions), - service, - 'Pause', - ); - - await service.setPauseStatus(false).then((tx) => tx.wait); - }); - - it('Should revert on execute with token with invalid messageType', async () => { - const symbol = 'TS3'; - const [token, , tokenId] = await deployFunctions.gateway(service, 'Name', symbol, 15, amount); - - await token.transfer(gateway.address, amount).then((tx) => tx.wait); - - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, sourceAddress, destAddress, amount], - ); - const commandId = await approveContractCallWithMint( - gateway, - sourceChain, - sourceAddress, - service.address, - payload, - symbol, - amount, - ); - - await expectRevert( - (gasOptions) => service.executeWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount, gasOptions), - service, - 'InvalidMessageType', - [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER], + 'NotSupported', ); }); }); @@ -1702,49 +1551,6 @@ describe('Interchain Token Service', () => { .and.to.emit(service, 'InterchainTransferReceived') .withArgs(commandId, tokenId, sourceChain, hexlify(wallet.address), destAddress, amount, HashZero); }); - - it('Should be able to receive gateway token', async () => { - const symbol = 'TT5'; - const [token, , tokenId] = await deployFunctions.gateway(service, 'Test Token Lock Unlock', symbol, 12, amount); - await token.transfer(gateway.address, amount).then((tx) => tx.wait); - - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount, '0x'], - ); - - const invalidCommandId = getRandomBytes32(); - - await expectRevert( - (gasOptions) => service.executeWithToken(invalidCommandId, sourceChain, sourceAddress, payload, symbol, amount, gasOptions), - service, - 'NotApprovedByGateway', - [], - ); - - const commandId = await approveContractCallWithMint( - gateway, - sourceChain, - sourceAddress, - service.address, - payload, - symbol, - amount, - ); - - await expect( - reportGas( - service.executeWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount), - 'Receive GMP INTERCHAIN_TRANSFER lock/unlock', - ), - ) - .to.emit(token, 'Transfer') - .withArgs(service.address, destAddress, amount) - .to.emit(token, 'Transfer') - .withArgs(gateway.address, service.address, amount) - .and.to.emit(service, 'InterchainTransferReceived') - .withArgs(commandId, tokenId, sourceChain, hexlify(wallet.address), destAddress, amount, HashZero); - }); }); describe('Send Token With Data', () => { @@ -1832,77 +1638,6 @@ describe('Interchain Token Service', () => { }); } - it('Should initiate an interchain token transfer via the interchainTransfer standard contract call & express call [gateway]', async () => { - const symbol = 'TT1'; - const [token, , tokenId] = await deployFunctions.gateway(service, 'Test Token gateway', symbol, 12, amount * 3); - const sendAmount = amount; - const metadata = '0x00000000'; - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, sourceAddress, destAddress, sendAmount, '0x'], - ); - const payloadHash = keccak256(payload); - - const metadataExpress = '0x00000001'; - - const transferToAddress = service.address; - await expectRevert( - (gasOptions) => - service.interchainTransfer(tokenId, 'Untrusted Chain', destAddress, amount, metadata, gasValue, { - value: gasValue, - ...gasOptions, - }), - service, - 'UntrustedChain', - [], - ); - - await expect( - reportGas( - service.interchainTransfer(tokenId, destinationChain, destAddress, amount, metadata, gasValue, { value: gasValue }), - 'Call service.interchainTransfer with metadata gateway', - ), - ) - .to.emit(token, 'Transfer') - .withArgs(wallet.address, transferToAddress, amount) - .and.to.emit(gateway, 'ContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, payload, symbol, amount) - .and.to.emit(gasService, 'NativeGasPaidForContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, symbol, amount, gasValue, wallet.address) - .to.emit(service, 'InterchainTransfer') - .withArgs(tokenId, sourceAddress, destinationChain, destAddress, sendAmount, HashZero); - - await expect( - reportGas( - service.interchainTransfer(tokenId, destinationChain, destAddress, amount, metadata, 0), - 'Call service.interchainTransfer with metadata gateway (gas value zero)', - ), - ) - .to.emit(token, 'Transfer') - .withArgs(wallet.address, transferToAddress, amount) - .and.to.emit(gateway, 'ContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, payload, symbol, amount) - .to.emit(service, 'InterchainTransfer') - .withArgs(tokenId, sourceAddress, destinationChain, destAddress, sendAmount, HashZero); - - await expect( - reportGas( - service.interchainTransfer(tokenId, destinationChain, destAddress, amount, metadataExpress, gasValue, { - value: gasValue, - }), - 'Call service.interchainTransfer with metadata gateway (express call)', - ), - ) - .to.emit(token, 'Transfer') - .withArgs(wallet.address, transferToAddress, amount) - .and.to.emit(gateway, 'ContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, payload, symbol, amount) - .and.to.emit(gasService, 'NativeGasPaidForExpressCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, symbol, amount, gasValue, wallet.address) - .to.emit(service, 'InterchainTransfer') - .withArgs(tokenId, sourceAddress, destinationChain, destAddress, sendAmount, HashZero); - }); - it('Should revert on callContractWithInterchainToken function on the service if amount is 0', async () => { const [, , tokenId] = await deployFunctions.lockUnlock(service, 'Test Token', 'TT', 12, amount); @@ -2408,50 +2143,6 @@ describe('Interchain Token Service', () => { 'ZeroAmount', ); }); - - it('Should be able to initiate an interchain token transfer via interchainTransfer & interchainTransferFrom [gateway]', async () => { - const symbol = 'TT2'; - [token, tokenManager, tokenId] = await deployFunctions.gateway(service, 'Test Token gateway', symbol, 12, amount * 3, true); - const sendAmount = amount; - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, sendAmount, '0x'], - ); - const payloadHash = keccak256(payload); - - const transferToAddress = service.address; - - await expect( - reportGas( - token.connect(wallet).interchainTransfer(destinationChain, destAddress, amount, metadata, { value: gasValue }), - 'Call token.interchainTransfer gateway', - ), - ) - .and.to.emit(token, 'Transfer') - .withArgs(wallet.address, transferToAddress, amount) - .and.to.emit(gateway, 'ContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, payload, symbol, amount) - .and.to.emit(gasService, 'NativeGasPaidForContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, symbol, amount, gasValue, wallet.address) - .to.emit(service, 'InterchainTransfer') - .withArgs(tokenId, wallet.address, destinationChain, destAddress, sendAmount, HashZero); - - await token.approve(otherWallet.address, amount).then((tx) => tx.wait); - - await expect( - token - .connect(otherWallet) - .interchainTransferFrom(wallet.address, destinationChain, destAddress, amount, metadata, { value: gasValue }), - ) - .and.to.emit(token, 'Transfer') - .withArgs(wallet.address, transferToAddress, amount) - .and.to.emit(gateway, 'ContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, payload, symbol, amount) - .and.to.emit(gasService, 'NativeGasPaidForContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, symbol, amount, gasValue, otherWallet.address) - .to.emit(service, 'InterchainTransfer') - .withArgs(tokenId, wallet.address, destinationChain, destAddress, sendAmount, HashZero); - }); }); describe('Send Interchain Token With Data', () => { @@ -2493,31 +2184,6 @@ describe('Interchain Token Service', () => { .withArgs(tokenId, sourceAddress, destinationChain, destAddress, sendAmount, keccak256(data)); }); } - - it('Should be able to initiate an interchain token transfer [gateway]', async () => { - const symbol = 'TT3'; - const [token, , tokenId] = await deployFunctions.gateway(service, 'Test Token gateway', symbol, 12, amount, false); - const sendAmount = amount; - - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, sourceAddress, destAddress, sendAmount, data], - ); - const payloadHash = keccak256(payload); - - const transferToAddress = service.address; - - const metadata = solidityPack(['uint32', 'bytes'], [0, data]); - await expect(token.interchainTransfer(destinationChain, destAddress, amount, metadata, { value: gasValue })) - .and.to.emit(token, 'Transfer') - .withArgs(wallet.address, transferToAddress, amount) - .and.to.emit(gateway, 'ContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, payload, symbol, amount) - .and.to.emit(gasService, 'NativeGasPaidForContractCallWithToken') - .withArgs(service.address, destinationChain, service.address, payloadHash, symbol, amount, gasValue, wallet.address) - .to.emit(service, 'InterchainTransfer') - .withArgs(tokenId, sourceAddress, destinationChain, destAddress, sendAmount, keccak256(data)); - }); }); describe('Express Execute', () => { @@ -2655,7 +2321,7 @@ describe('Interchain Token Service', () => { }); }); - describe('Express Execute With Token', () => { + describe('Interchain Executable', () => { const commandId = getRandomBytes32(); const sourceAddress = '0x1234'; const amount = 1234; @@ -2667,15 +2333,12 @@ describe('Interchain Token Service', () => { let data; let tokenId; let executable; - let invalidExecutable; let token; before(async () => { - [token, , tokenId] = await deployFunctions.gateway(service, tokenName, tokenSymbol, tokenDecimals, amount * 2, true); - await token.approve(service.address, amount * 2).then((tx) => tx.wait); + [token, , tokenId] = await deployFunctions.mintBurn(service, tokenName, tokenSymbol, tokenDecimals, amount * 2, true); data = defaultAbiCoder.encode(['address', 'string'], [destinationAddress, message]); executable = await deployContract(wallet, 'TestInterchainExecutable', [service.address]); - invalidExecutable = await deployContract(wallet, 'TestInvalidInterchainExecutable', [service.address]); }); it('Should revert on executeWithInterchainToken when not called by the service', async () => { @@ -2716,7 +2379,7 @@ describe('Interchain Token Service', () => { ); }); - it('Should revert on express execute with token when service is paused', async () => { + it('Should revert on express execute when service is paused', async () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destinationAddress, amount, '0x'], @@ -2725,8 +2388,7 @@ describe('Interchain Token Service', () => { await service.setPauseStatus(true).then((tx) => tx.wait); await expectRevert( - (gasOptions) => - service.expressExecuteWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount, gasOptions), + (gasOptions) => service.expressExecute(commandId, sourceChain, sourceAddress, payload, gasOptions), service, 'Pause', ); @@ -2734,66 +2396,14 @@ describe('Interchain Token Service', () => { await service.setPauseStatus(false).then((tx) => tx.wait); }); - it('Should express execute with token', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destinationAddress, amount, '0x'], - ); - await expect(service.expressExecuteWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount)) - .to.emit(service, 'ExpressExecuted') - .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address) - .and.to.emit(token, 'Transfer') - .withArgs(wallet.address, destinationAddress, amount); - }); - - it('Should revert on express execute if token handler transfer token from fails', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', ' bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, sourceAddress, AddressZero, amount, data], - ); - - const errorSignatureHash = id('TokenTransferFailed()'); - const errorData = errorSignatureHash.substring(0, 10); - - await expectRevert( - (gasOptions) => - service.expressExecuteWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount, gasOptions), - service, - 'TokenHandlerFailed', - [errorData], - ); - }); - - it('Should revert on express execute with token if token transfer fails on destination chain', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', ' bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, sourceAddress, invalidExecutable.address, amount, data], - ); - + it('Should revert on express execute with token', async () => { await expectRevert( (gasOptions) => - service.expressExecuteWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount, gasOptions), + service.expressExecuteWithToken(commandId, sourceChain, sourceAddress, '0x', tokenSymbol, amount, gasOptions), service, - 'ExpressExecuteWithInterchainTokenFailed', - [invalidExecutable.address], + 'NotSupported', ); }); - - it('Should express execute with token', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', ' bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, sourceAddress, executable.address, amount, data], - ); - await expect(service.expressExecuteWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount)) - .to.emit(service, 'ExpressExecuted') - .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address) - .and.to.emit(token, 'Transfer') - .withArgs(wallet.address, executable.address, amount) - .and.to.emit(token, 'Transfer') - .withArgs(executable.address, destinationAddress, amount) - .and.to.emit(executable, 'MessageReceived') - .withArgs(commandId, sourceChain, sourceAddress, destinationAddress, message, tokenId, amount); - }); }); describe('Express Receive Remote Token', () => { @@ -2843,7 +2453,7 @@ describe('Interchain Token Service', () => { ); }); - it('Should be able to receive lock/unlock token', async () => { + it('Should be able to receive lock_unlock token', async () => { await token.transfer(tokenManager.address, amount).then((tx) => tx.wait); await token.approve(service.address, amount).then((tx) => tx.wait); @@ -2863,7 +2473,7 @@ describe('Interchain Token Service', () => { .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address); }); - it('Should be able to receive interchain mint/burn token', async () => { + it('Should be able to receive native_interchain token', async () => { const salt = getRandomBytes32(); await (await service.deployInterchainToken(salt, '', 'Test Token Mint Burn', 'TT', 12, wallet.address, 0)).wait(); const tokenId = await service.interchainTokenId(wallet.address, salt); @@ -2888,7 +2498,7 @@ describe('Interchain Token Service', () => { .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address); }); - it('Should be able to receive mint/burn token', async () => { + it('Should be able to receive mint_burn token', async () => { const [token, , tokenId] = await deployFunctions.mintBurn(service, 'Test Token Mint Burn', 'TT', 12, amount); await token.approve(service.address, amount).then((tx) => tx.wait); @@ -2909,7 +2519,7 @@ describe('Interchain Token Service', () => { .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address); }); - it('Should be able to receive mint/burn from token', async () => { + it('Should be able to receive mint_burn_from token', async () => { const [token, , tokenId] = await deployFunctions.mintBurnFrom(service, 'Test Token Mint Burn From', 'TT', 12, amount); await token.approve(service.address, amount).then((tx) => tx.wait); @@ -2930,7 +2540,7 @@ describe('Interchain Token Service', () => { .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address); }); - it('Should be able to receive lock/unlock with fee on transfer token', async () => { + it('Should be able to receive lock_unlock_with_fee token', async () => { const [token, tokenManager, tokenId] = await deployFunctions.lockUnlockFee( service, 'Test Token Lock Unlock', @@ -2957,7 +2567,7 @@ describe('Interchain Token Service', () => { .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address); }); - it('Should be able to receive lock/unlock with fee on transfer token with normal ERC20 token', async () => { + it('Should be able to receive lock_unlock_with_fee token with normal ERC20 token', async () => { const [token, tokenManager, tokenId] = await deployFunctions.lockUnlockFee( service, 'Test Token Lock Unlock', @@ -2985,42 +2595,6 @@ describe('Interchain Token Service', () => { .and.to.emit(service, 'ExpressExecutionFulfilled') .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address); }); - - it('Should be able to receive mint/burn token', async () => { - const symbol = 'TT4'; - const [token, , tokenId] = await deployFunctions.gateway(service, 'Test Token Mint Burn', symbol, 12, 2 * amount); - - await token.approve(service.address, amount).then((tx) => tx.wait); - await token.transfer(gateway.address, amount).then((tx) => tx.wait); - - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount, '0x'], - ); - - const commandId = getRandomBytes32(); - await service.expressExecuteWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount).then((tx) => tx.wait); - await approveContractCallWithMint( - gateway, - sourceChain, - sourceAddress, - service.address, - payload, - symbol, - amount, - getRandomBytes32(), - 0, - commandId, - ); - - await expect(service.executeWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount)) - .to.emit(token, 'Transfer') - .withArgs(gateway.address, service.address, amount) - .to.emit(token, 'Transfer') - .withArgs(service.address, wallet.address, amount) - .and.to.emit(service, 'ExpressExecutionFulfilled') - .withArgs(commandId, sourceChain, sourceAddress, keccak256(payload), wallet.address); - }); }); describe('Express Receive Remote Token with Data', () => { @@ -3036,7 +2610,7 @@ describe('Interchain Token Service', () => { destAddress = executable.address; }); - it('Should be able to receive lock/unlock token', async () => { + it('Should be able to receive lock_unlock token', async () => { const [token, tokenManager, tokenId] = await deployFunctions.lockUnlock( service, 'Test Token Lock Unlock', @@ -3068,7 +2642,7 @@ describe('Interchain Token Service', () => { expect(await executable.lastMessage()).to.equal(msg); }); - it('Should be able to receive interchain mint/burn token', async () => { + it('Should be able to receive native_interchain token', async () => { const salt = getRandomBytes32(); await (await service.deployInterchainToken(salt, '', 'Test Token Mint Burn', 'TT', 12, wallet.address, 0)).wait(); const tokenId = await service.interchainTokenId(wallet.address, salt); @@ -3096,7 +2670,8 @@ describe('Interchain Token Service', () => { expect(await executable.lastMessage()).to.equal(msg); }); - it('Should be able to receive mint/burn token', async () => { + + it('Should be able to receive mint_burn token', async () => { const [token, , tokenId] = await deployFunctions.mintBurn(service, 'Test Token Mint Burn', 'TT', 12, amount); await token.approve(service.address, amount).then((tx) => tx.wait); @@ -3120,7 +2695,7 @@ describe('Interchain Token Service', () => { expect(await executable.lastMessage()).to.equal(msg); }); - it('Should be able to receive lock/unlock with fee on transfer token', async () => { + it('Should be able to receive lock_unlock_with_fee token', async () => { const [token, tokenManager, tokenId] = await deployFunctions.lockUnlockFee( service, 'Test Token Lock Unlock', @@ -3395,100 +2970,12 @@ describe('Interchain Token Service', () => { }); describe('Call contract with token value', () => { - const trustedAddress = 'Trusted address with token'; - const name = 'Gateway Token'; - const symbol = 'GT'; - const decimals = 18; - const message = 0; - const amount = 100; - let tokenId; - - before(async () => { - [, , tokenId] = await deployFunctions.gateway(service, name, symbol, decimals); - }); - - it('Should revert on contractCallWithTokenValue if not called by remote service', async () => { - const payload = '0x'; - - await expectRevert( - (gasOptions) => service.contractCallWithTokenValue(sourceChain, trustedAddress, payload, symbol, 0, gasOptions), - service, - 'NotRemoteService', - ); - }); - - it('Should revert on contractCallWithTokenValue if service is paused', async () => { - const payload = '0x'; - - await service.setTrustedAddress(sourceChain, trustedAddress).then((tx) => tx.wait); - - await service.setPauseStatus(true).then((tx) => tx.wait); - + it('Should revert on contract call value', async () => { await expectRevert( - (gasOptions) => service.contractCallWithTokenValue(sourceChain, trustedAddress, payload, symbol, 0, gasOptions), + (gasOptions) => service.contractCallWithTokenValue(sourceChain, 'sourceAddress', '0x', 'TEST', 1, gasOptions), service, - 'Pause', - ); - - await service.setPauseStatus(false).then((tx) => tx.wait); - }); - - it('Should revert on invalid express message type', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [message + 1, tokenId, '0x', '0x', amount, '0x'], - ); - await expectRevert( - (gasOptions) => service.contractCallWithTokenValue(sourceChain, trustedAddress, payload, symbol, amount, gasOptions), - service, - 'InvalidExpressMessageType', - [message + 1], - ); - }); - - it('Should revert on token missmatch', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [message, tokenId, '0x', '0x', amount, '0x'], - ); - await expectRevert( - (gasOptions) => - service.contractCallWithTokenValue(sourceChain, trustedAddress, payload, 'wrong symbol', amount, gasOptions), - service, - 'InvalidGatewayTokenTransfer', - [tokenId, payload, 'wrong symbol', amount], - ); - }); - - it('Should revert on amount missmatch', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [message, tokenId, '0x', '0x', amount, '0x'], - ); - await expectRevert( - (gasOptions) => service.contractCallWithTokenValue(sourceChain, trustedAddress, payload, symbol, amount + 1, gasOptions), - service, - 'InvalidGatewayTokenTransfer', - [tokenId, payload, symbol, amount + 1], - ); - }); - - it('Should return correct token address and amount', async () => { - const payload = defaultAbiCoder.encode( - ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [message, tokenId, '0x', '0x', amount, '0x'], - ); - - const [tokenAddress, returnedAmount] = await service.contractCallWithTokenValue( - sourceChain, - trustedAddress, - payload, - symbol, - amount, + 'NotSupported', ); - - expect(tokenAddress).to.eq(await service.validTokenAddress(tokenId)); - expect(returnedAmount).to.eq(amount); }); }); diff --git a/test/InterchainTokenServiceUpgradeFlow.js b/test/InterchainTokenServiceUpgradeFlow.js index de145646..ce5a2965 100644 --- a/test/InterchainTokenServiceUpgradeFlow.js +++ b/test/InterchainTokenServiceUpgradeFlow.js @@ -73,7 +73,7 @@ describe('Interchain Token Service Upgrade Flow', () => { tokenManagerDeployer = await deployContract(wallet, 'TokenManagerDeployer', []); interchainTokenDeployer = await deployContract(wallet, 'InterchainTokenDeployer', [interchainToken.address]); tokenManager = await deployContract(wallet, 'TokenManager', [interchainTokenServiceAddress]); - tokenHandler = await deployContract(wallet, 'TokenHandler', [gateway.address]); + tokenHandler = await deployContract(wallet, 'TokenHandler', []); gatewayCaller = await deployContract(wallet, 'GatewayCaller', [gateway.address, gasService.address]); interchainTokenFactoryAddress = await getCreate3Address(create3Deployer.address, wallet, deploymentKey + 'Factory'); diff --git a/test/constants.js b/test/constants.js index b235d864..a4fef332 100644 --- a/test/constants.js +++ b/test/constants.js @@ -12,7 +12,6 @@ const MINT_BURN_FROM = 1; const LOCK_UNLOCK = 2; const LOCK_UNLOCK_FEE_ON_TRANSFER = 3; const MINT_BURN = 4; -const GATEWAY = 5; const MINTER_ROLE = 0; const OPERATOR_ROLE = 1; @@ -35,7 +34,6 @@ module.exports = { LOCK_UNLOCK, LOCK_UNLOCK_FEE_ON_TRANSFER, MINT_BURN, - GATEWAY, MINTER_ROLE, OPERATOR_ROLE, FLOW_LIMITER_ROLE,