diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 23773890..e3c5651b 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -35,7 +35,7 @@ jobs: if grep -q -i "error" build.log || grep -q -i "warning" build.log; then echo "Build contains following errors or warnings..." cat build.log - exit 0; + exit 1; else exit 0; fi diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4070574f..276e0d04 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -33,7 +33,7 @@ jobs: cat build.log - exit 0; + exit 1; else exit 0; fi diff --git a/contracts/InterchainTokenFactory.sol b/contracts/InterchainTokenFactory.sol index ab85101e..2c042e58 100644 --- a/contracts/InterchainTokenFactory.sol +++ b/contracts/InterchainTokenFactory.sol @@ -27,6 +27,7 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M 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); /** @@ -71,6 +72,15 @@ 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. @@ -285,13 +295,16 @@ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, M /** * @notice Register 'canonical' gateway tokens. The same salt needs to be used for the same gateway token on every chain. - * @param salt The salt to be used for the token registration. Should be the same for all tokens and something that will not have collisions with any of the other salts used by the factory. + * @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 salt, string calldata symbol) external onlyOwner returns (bytes32 tokenId) { + 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 8fe0db1f..b997e98e 100644 --- a/contracts/InterchainTokenService.sol +++ b/contracts/InterchainTokenService.sol @@ -290,7 +290,7 @@ contract InterchainTokenService is bytes calldata params, uint256 gasValue ) external payable whenNotPaused returns (bytes32 tokenId) { - // Custom token managers can't be deployed with Interchain token mint burn type, which is reserved for interchain tokens + // Custom token managers can't be deployed with native interchain token type, which is reserved for interchain tokens if (tokenManagerType == TokenManagerType.NATIVE_INTERCHAIN_TOKEN) revert CannotDeploy(tokenManagerType); address deployer = msg.sender; diff --git a/contracts/TokenHandler.sol b/contracts/TokenHandler.sol index 95a82c47..14fac5a9 100644 --- a/contracts/TokenHandler.sol +++ b/contracts/TokenHandler.sol @@ -166,7 +166,8 @@ contract TokenHandler is ITokenHandler, ITokenManagerType, ReentrancyGuard, Crea 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. + // 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); diff --git a/contracts/interfaces/IInterchainTokenFactory.sol b/contracts/interfaces/IInterchainTokenFactory.sol index 65301562..c9751c05 100644 --- a/contracts/interfaces/IInterchainTokenFactory.sol +++ b/contracts/interfaces/IInterchainTokenFactory.sol @@ -130,10 +130,17 @@ interface IInterchainTokenFactory is IUpgradable, IMulticall { 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 salt The salt to be used for the token registration. Should be the same for all tokens and something that will not have collisions with any of the other salts used by the factory. + * @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 salt, string calldata symbol) external returns (bytes32 tokenId); + function registerGatewayToken(bytes32 tokenIdentifier, string calldata symbol) external returns (bytes32 tokenId); } diff --git a/hardhat.config.js b/hardhat.config.js index 279489a7..065cc4f3 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -10,9 +10,6 @@ const chains = require(`@axelar-network/axelar-chains-config/info/${env}.json`); const keys = readJSON(`${__dirname}/keys.json`); const { networks, etherscan } = importNetworks(chains, keys); -// TODO: Remove this temporary override -networks.hardhat.allowUnlimitedContractSize = true; - const optimizerSettings = { enabled: true, runs: 1000, @@ -38,12 +35,12 @@ const compilerSettings = { }, }; const itsCompilerSettings = { - version: '0.8.21', + version: '0.8.24', settings: { evmVersion: process.env.EVM_VERSION || 'london', optimizer: { ...optimizerSettings, - runs: 100, // Reduce runs to keep bytecode size under limit + runs: 150, // Reduce runs to keep bytecode size under limit }, }, }; @@ -76,7 +73,7 @@ module.exports = { }, contractSizer: { runOnCompile: process.env.CHECK_CONTRACT_SIZE, - // strict: process.env.CHECK_CONTRACT_SIZE, // TODO: uncomment this + strict: process.env.CHECK_CONTRACT_SIZE, except: ['contracts/test'], }, }; diff --git a/package-lock.json b/package-lock.json index fbe7e116..4d175e75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@axelar-network/interchain-token-service", - "version": "1.2.4", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@axelar-network/interchain-token-service", - "version": "1.2.4", + "version": "2.0.0", "license": "MIT", "dependencies": { "@axelar-network/axelar-cgp-solidity": "6.2.1", diff --git a/package.json b/package.json index dd930eb3..2ff7cf24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@axelar-network/interchain-token-service", - "version": "1.2.4", + "version": "2.0.0", "repository": { "type": "git", "url": "https://github.com/axelarnetwork/interchain-token-service" diff --git a/test/InterchainTokenFactory.js b/test/InterchainTokenFactory.js index ffdbeb06..0167d891 100644 --- a/test/InterchainTokenFactory.js +++ b/test/InterchainTokenFactory.js @@ -7,7 +7,7 @@ const { getContractAt, Wallet, constants: { AddressZero }, - utils: { defaultAbiCoder, keccak256, toUtf8Bytes }, + utils: { defaultAbiCoder, keccak256, toUtf8Bytes, id }, } = ethers; const { deployAll, deployContract } = require('../scripts/deploy'); const { getRandomBytes32, expectRevert } = require('./utils'); @@ -188,7 +188,8 @@ describe('InterchainTokenFactory', () => { await gateway.deployToken(params, getRandomBytes32()).then((tx) => tx.wait); - tokenId = await service.interchainTokenId(AddressZero, salt); + 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) {