diff --git a/contracts/interchain-token-service/InterchainTokenService.sol b/contracts/interchain-token-service/InterchainTokenService.sol index 7a813a4b..6b9e1966 100644 --- a/contracts/interchain-token-service/InterchainTokenService.sol +++ b/contracts/interchain-token-service/InterchainTokenService.sol @@ -46,36 +46,45 @@ contract InterchainTokenService is using AddressBytes for address; using SafeTokenTransferFrom for IERC20; + IAxelarGateway public immutable gateway; + IAxelarGasService public immutable gasService; + bytes32 public immutable chainNameHash; + + address public immutable interchainTokenDeployer; + address public immutable tokenManagerDeployer; + + /** + * @dev Token manager implementation addresses + */ address internal immutable implementationLockUnlock; + address internal immutable implementationLockUnlockFee; address internal immutable implementationMintBurn; address internal immutable implementationMintBurnFrom; - address internal immutable implementationLockUnlockFee; - IAxelarGateway public immutable gateway; - IAxelarGasService public immutable gasService; + IInterchainAddressTracker public immutable interchainAddressTracker; - address public immutable tokenManagerDeployer; - address public immutable interchainTokenDeployer; - bytes32 public immutable chainNameHash; bytes32 internal constant PREFIX_TOKEN_ID = keccak256('its-custom-token-id'); bytes32 internal constant PREFIX_INTERCHAIN_TOKEN_SALT = keccak256('its-interchain-token-salt'); - uint256 private constant SELECTOR_RECEIVE_TOKEN = 1; - uint256 private constant SELECTOR_RECEIVE_TOKEN_WITH_DATA = 2; - uint256 private constant SELECTOR_DEPLOY_TOKEN_MANAGER = 3; - uint256 private constant SELECTOR_DEPLOY_INTERCHAIN_TOKEN = 4; - bytes32 private constant CONTRACT_ID = keccak256('interchain-token-service'); bytes32 private constant EXECUTE_SUCCESS = keccak256('its-execute-success'); bytes32 private constant EXPRESS_EXECUTE_SUCCESS = keccak256('its-express-execute-success'); + /** + * @dev The message types that are sent between InterchainTokenService on different chains. + */ + uint256 private constant MESSAGE_TYPE_INTERCHAIN_TRANSFER = 1; + uint256 private constant MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA = 2; + uint256 private constant MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER = 3; + uint256 private constant MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN = 4; + /** * @dev All of the variables passed here are stored as immutable variables. * @param tokenManagerDeployer_ the address of the TokenManagerDeployer. * @param interchainTokenDeployer_ the address of the InterchainTokenDeployer. * @param gateway_ the address of the AxelarGateway. * @param gasService_ the address of the AxelarGasService. - * @param interchainRouter_ the address of the InterchainAddressTracker. + * @param interchainAddressTracker_ the address of the InterchainAddressTracker. * @param tokenManagerImplementations this needs to have implementations in the order: Mint-burn, Mint-burn from, Lock-unlock, and Lock-unlock with fee. */ constructor( @@ -83,11 +92,11 @@ contract InterchainTokenService is address interchainTokenDeployer_, address gateway_, address gasService_, - address interchainRouter_, + address interchainAddressTracker_, address[] memory tokenManagerImplementations ) { if ( - interchainRouter_ == address(0) || + interchainAddressTracker_ == address(0) || gasService_ == address(0) || tokenManagerDeployer_ == address(0) || interchainTokenDeployer_ == address(0) || @@ -95,7 +104,7 @@ contract InterchainTokenService is ) revert ZeroAddress(); gateway = IAxelarGateway(gateway_); - interchainAddressTracker = IInterchainAddressTracker(interchainRouter_); + interchainAddressTracker = IInterchainAddressTracker(interchainAddressTracker_); gasService = IAxelarGasService(gasService_); tokenManagerDeployer = tokenManagerDeployer_; interchainTokenDeployer = interchainTokenDeployer_; @@ -106,6 +115,7 @@ contract InterchainTokenService is implementationMintBurnFrom = _sanitizeTokenManagerImplementation(tokenManagerImplementations, TokenManagerType.MINT_BURN_FROM); implementationLockUnlock = _sanitizeTokenManagerImplementation(tokenManagerImplementations, TokenManagerType.LOCK_UNLOCK); implementationLockUnlockFee = _sanitizeTokenManagerImplementation(tokenManagerImplementations, TokenManagerType.LOCK_UNLOCK_FEE); + string memory chainName_ = interchainAddressTracker.chainName(); chainNameHash = keccak256(bytes(chainName_)); } @@ -121,6 +131,7 @@ contract InterchainTokenService is */ modifier onlyRemoteService(string calldata sourceChain, string calldata sourceAddress) { if (!interchainAddressTracker.isTrustedAddress(sourceChain, sourceAddress)) revert NotRemoteService(); + _; } @@ -187,8 +198,7 @@ contract InterchainTokenService is } /** - * @notice Calculates the tokenId that would correspond to a custom link for a given deployer with a specified salt. - * This will not depend on what chain it is called from, unlike canonical tokenIds. + * @notice Calculates the tokenId that would correspond to a link for a given deployer with a specified salt. * @param sender the address of the TokenManager deployer. * @param salt the salt that the deployer uses for the deployment. * @return tokenId the tokenId that the custom TokenManager would get (or has gotten). @@ -266,10 +276,11 @@ contract InterchainTokenService is bytes calldata params, uint256 gasValue ) external payable whenNotPaused returns (bytes32 tokenId) { - address deployer_ = msg.sender; - tokenId = interchainTokenId(deployer_, salt); + address deployer = msg.sender; + tokenId = interchainTokenId(deployer, salt); + + emit InterchainTokenIdClaimed(tokenId, deployer, salt); - emit CustomTokenIdClaimed(tokenId, deployer_, salt); if (bytes(destinationChain).length == 0) { _deployTokenManager(tokenId, tokenManagerType, params); } else { @@ -303,8 +314,8 @@ contract InterchainTokenService is bytes32 tokenId = interchainTokenId(msg.sender, salt); if (bytes(destinationChain).length == 0) { - address tokenAddress_; - tokenAddress_ = _deployInterchainToken(tokenId, distributor, name, symbol, decimals); + address tokenAddress_ = _deployInterchainToken(tokenId, distributor, name, symbol, decimals); + _deployTokenManager(tokenId, TokenManagerType.MINT_BURN, abi.encode(operator, tokenAddress_)); } else { _deployRemoteInterchainToken(tokenId, name, symbol, decimals, distributor, operator, destinationChain, gasValue); @@ -317,10 +328,10 @@ contract InterchainTokenService is string calldata sourceAddress, bytes calldata payload ) public view virtual onlyRemoteService(sourceChain, sourceAddress) whenNotPaused returns (address, uint256) { - (uint256 selector, bytes32 tokenId, , uint256 amount) = abi.decode(payload, (uint256, bytes32, bytes, uint256)); + (uint256 messageType, bytes32 tokenId, , uint256 amount) = abi.decode(payload, (uint256, bytes32, bytes, uint256)); - if (selector != SELECTOR_RECEIVE_TOKEN && selector != SELECTOR_RECEIVE_TOKEN_WITH_DATA) { - revert InvalidExpressSelector(selector); + if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER && messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA) { + revert InvalidExpressMessageType(messageType); } ITokenManager tokenManager = ITokenManager(validTokenManagerAddress(tokenId)); @@ -333,10 +344,11 @@ contract InterchainTokenService is string calldata sourceAddress, bytes calldata payload ) external payable whenNotPaused { - uint256 selector = abi.decode(payload, (uint256)); - if (selector != SELECTOR_RECEIVE_TOKEN && selector != SELECTOR_RECEIVE_TOKEN_WITH_DATA) { - revert InvalidExpressSelector(selector); + uint256 messageType = abi.decode(payload, (uint256)); + if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER && messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA) { + revert InvalidExpressMessageType(messageType); } + if (gateway.isCommandExecuted(commandId)) revert AlreadyExecuted(); address expressExecutor = msg.sender; @@ -356,10 +368,8 @@ contract InterchainTokenService is * @param payload the payload of the receive token */ function _expressExecute(string calldata sourceChain, bytes calldata payload) internal { - (uint256 selector, bytes32 tokenId, bytes memory sourceAddress, bytes memory destinationAddressBytes, uint256 amount) = abi.decode( - payload, - (uint256, bytes32, bytes, bytes, uint256) - ); + (uint256 messageType, bytes32 tokenId, bytes memory sourceAddress, bytes memory destinationAddressBytes, uint256 amount) = abi + .decode(payload, (uint256, bytes32, bytes, bytes, uint256)); address destinationAddress = destinationAddressBytes.toAddress(); IERC20 token; @@ -370,7 +380,7 @@ contract InterchainTokenService is token.safeTransferFrom(msg.sender, destinationAddress, amount); - if (selector == SELECTOR_RECEIVE_TOKEN_WITH_DATA) { + if (messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA) { (, , , , , bytes memory data) = abi.decode(payload, (uint256, bytes32, bytes, bytes, uint256, bytes)); bytes32 result = IInterchainTokenExpressExecutable(destinationAddress).expressExecuteWithInterchainToken( @@ -403,10 +413,10 @@ contract InterchainTokenService is ) external payable whenNotPaused { ITokenManager tokenManager = ITokenManager(tokenManagerAddress(tokenId)); amount = tokenManager.takeToken(msg.sender, amount); - _transmitSendToken(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadata); + _transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadata); } - function sendTokenWithData( + function callContractWithInterchainToken( bytes32 tokenId, string calldata destinationChain, bytes calldata destinationAddress, @@ -416,7 +426,7 @@ contract InterchainTokenService is ITokenManager tokenManager = ITokenManager(tokenManagerAddress(tokenId)); amount = tokenManager.takeToken(msg.sender, amount); uint32 prefix = 0; - _transmitSendToken(tokenId, msg.sender, destinationChain, destinationAddress, amount, abi.encodePacked(prefix, data)); + _transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, abi.encodePacked(prefix, data)); } /*********************\ @@ -424,7 +434,7 @@ contract InterchainTokenService is \*********************/ /** - * @notice Transmit a sendTokenWithData for the given tokenId. Only callable by a token manager. + * @notice Transmit an interchain transfer for the given tokenId. Only callable by a token manager. * @param tokenId the tokenId of the TokenManager (which must be the msg.sender). * @param sourceAddress the address where the token is coming from, which will also be used for reimbursement of gas. * @param destinationChain the name of the chain to send tokens to. @@ -432,7 +442,7 @@ contract InterchainTokenService is * @param amount the amount of token to give. * @param metadata the data to be passed to the destination. */ - function transmitSendToken( + function transmitInterchainTransfer( bytes32 tokenId, address sourceAddress, string calldata destinationChain, @@ -440,7 +450,7 @@ contract InterchainTokenService is uint256 amount, bytes calldata metadata ) external payable onlyTokenManager(tokenId) whenNotPaused { - _transmitSendToken(tokenId, sourceAddress, destinationChain, destinationAddress, amount, metadata); + _transmitInterchainTransfer(tokenId, sourceAddress, destinationChain, destinationAddress, amount, metadata); } /*************\ @@ -455,6 +465,7 @@ contract InterchainTokenService is function setFlowLimits(bytes32[] calldata tokenIds, uint256[] calldata flowLimits) external onlyRole(uint8(Roles.OPERATOR)) { uint256 length = tokenIds.length; if (length != flowLimits.length) revert LengthMismatch(); + for (uint256 i; i < length; ++i) { ITokenManager tokenManager = ITokenManager(validTokenManagerAddress(tokenIds[i])); // slither-disable-next-line calls-loop @@ -463,12 +474,15 @@ contract InterchainTokenService is } /** - * @notice Used to pause the entire service. - * @param paused what value to set paused to. + * @notice Allows the owner to pause/unpause the token service. + * @param paused whether to pause or unpause. */ - function setPaused(bool paused) external onlyOwner { - _setPaused(paused); - emit PausedSet(paused, msg.sender); + function setPauseStatus(bool paused) external onlyOwner { + if (paused) { + _pause(); + } else { + _unpause(); + } } /****************\ @@ -485,12 +499,13 @@ contract InterchainTokenService is ) internal pure returns (address implementation_) { implementation_ = tokenManagerImplementations[uint256(tokenManagerType)]; if (implementation_ == address(0)) revert ZeroAddress(); + if (ITokenManager(implementation_).implementationType() != uint256(tokenManagerType)) revert InvalidTokenManagerImplementationType(implementation_); } /** - * @notice Executes operations based on the payload and selector. + * @notice Executes operations based on the payload and messageType. * @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 @@ -505,21 +520,22 @@ contract InterchainTokenService is if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); - uint256 selector = abi.decode(payload, (uint256)); - if (selector == SELECTOR_RECEIVE_TOKEN || selector == SELECTOR_RECEIVE_TOKEN_WITH_DATA) { + uint256 messageType = abi.decode(payload, (uint256)); + if (messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER || messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA) { address expressExecutor = _popExpressExecutor(commandId, sourceChain, sourceAddress, payloadHash); - _processReceiveTokenPayload(expressExecutor, sourceChain, payload, selector); - if (expressExecutor != address(0)) - emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); + _processInterchainTransferPayload(expressExecutor, sourceChain, payload, messageType); - return; + if (expressExecutor != address(0)) { + emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); + } + } else if (messageType == MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER) { + _processDeployTokenManagerPayload(payload); + } else if (messageType == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN) { + _processDeployInterchainTokenPayload(payload); + } else { + revert InvalidMessageType(messageType); } - - if (selector == SELECTOR_DEPLOY_TOKEN_MANAGER) return _processDeployTokenManagerPayload(payload); - if (selector == SELECTOR_DEPLOY_INTERCHAIN_TOKEN) return _processDeployInterchainTokenPayload(payload); - - revert SelectorUnknown(selector); } function contractCallWithTokenValue( @@ -559,11 +575,11 @@ contract InterchainTokenService is * @param sourceChain The chain where the transaction originates from * @param payload The encoded data payload to be processed */ - function _processReceiveTokenPayload( + function _processInterchainTransferPayload( address expressExecutor, string calldata sourceChain, bytes calldata payload, - uint256 selector + uint256 messageType ) internal { bytes32 tokenId; bytes memory sourceAddress; @@ -586,12 +602,12 @@ contract InterchainTokenService is amount = tokenManager.giveToken(destinationAddress, amount); - if (selector == SELECTOR_RECEIVE_TOKEN_WITH_DATA) { + if (messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA) { bytes memory data; (, , , , , data) = abi.decode(payload, (uint256, bytes32, bytes, bytes, uint256, bytes)); // slither-disable-next-line reentrancy-events - emit TokenReceivedWithData(tokenId, sourceChain, sourceAddress, destinationAddress, amount); + emit InterchainTransferReceivedWithData(tokenId, sourceChain, sourceAddress, destinationAddress, amount); bytes32 result = IInterchainTokenExecutable(destinationAddress).executeWithInterchainToken( sourceChain, @@ -605,7 +621,7 @@ contract InterchainTokenService is if (result != EXECUTE_SUCCESS) revert ExecuteWithInterchainTokenFailed(destinationAddress); } else { // slither-disable-next-line reentrancy-events - emit TokenReceived(tokenId, sourceChain, sourceAddress, destinationAddress, amount); + emit InterchainTransferReceived(tokenId, sourceChain, sourceAddress, destinationAddress, amount); } } @@ -687,9 +703,11 @@ contract InterchainTokenService is ) internal { // slither-disable-next-line unused-return validTokenManagerAddress(tokenId); - emit RemoteTokenManagerDeploymentInitialized(tokenId, destinationChain, gasValue, tokenManagerType, params); - bytes memory payload = abi.encode(SELECTOR_DEPLOY_TOKEN_MANAGER, tokenId, tokenManagerType, params); + emit TokenManagerDeploymentStarted(tokenId, destinationChain, tokenManagerType, params); + + bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, tokenManagerType, params); + _callContract(destinationChain, payload, gasValue); } @@ -717,9 +735,10 @@ contract InterchainTokenService is validTokenManagerAddress(tokenId); // slither-disable-next-line reentrancy-events - emit RemoteInterchainTokenDeploymentInitialized(tokenId, name, symbol, decimals, distributor, operator, destinationChain, gasValue); + emit InterchainTokenDeploymentStarted(tokenId, name, symbol, decimals, distributor, operator, destinationChain); + + bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, tokenId, name, symbol, decimals, distributor, operator); - bytes memory payload = abi.encode(SELECTOR_DEPLOY_INTERCHAIN_TOKEN, tokenId, name, symbol, decimals, distributor, operator); _callContract(destinationChain, payload, gasValue); } @@ -814,15 +833,15 @@ contract InterchainTokenService is } /** - * @notice Transmit a sendTokenWithData for the given tokenId. Only callable by a token manager. + * @notice Transmit a callContractWithInterchainToken for the given tokenId. Only callable by a token manager. * @param tokenId the tokenId of the TokenManager (which must be the msg.sender). * @param sourceAddress the address where the token is coming from, which will also be used for reimburment of gas. * @param destinationChain the name of the chain to send tokens to. * @param destinationAddress the destinationAddress for the interchainTransfer. * @param amount the amount of token to give. - * @param metadata the data to be passed to the destiantion. + * @param metadata the data to be passed to the destination. */ - function _transmitSendToken( + function _transmitInterchainTransfer( bytes32 tokenId, address sourceAddress, string calldata destinationChain, @@ -833,9 +852,9 @@ contract InterchainTokenService is bytes memory payload; if (metadata.length < 4) { // slither-disable-next-line reentrancy-events - emit TokenSent(tokenId, destinationChain, destinationAddress, amount); + emit InterchainTransfer(tokenId, destinationChain, destinationAddress, amount); - payload = abi.encode(SELECTOR_RECEIVE_TOKEN, tokenId, sourceAddress.toBytes(), destinationAddress, amount); + payload = abi.encode(MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, sourceAddress.toBytes(), destinationAddress, amount); _callContract(destinationChain, payload, msg.value); return; @@ -845,9 +864,16 @@ contract InterchainTokenService is if (version > 0) revert InvalidMetadataVersion(version); // slither-disable-next-line reentrancy-events - emit TokenSentWithData(tokenId, destinationChain, destinationAddress, amount, sourceAddress, metadata); - - payload = abi.encode(SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddress.toBytes(), destinationAddress, amount, metadata); + emit InterchainTransferWithData(tokenId, destinationChain, destinationAddress, amount, sourceAddress, metadata); + + payload = abi.encode( + MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, + tokenId, + sourceAddress.toBytes(), + destinationAddress, + amount, + metadata + ); _callContract(destinationChain, payload, msg.value); } diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 9f524ba7..45fabc7a 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -18,19 +18,18 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec error TokenManagerDoesNotExist(bytes32 tokenId); error NotTokenManager(address caller, address tokenManager); error ExecuteWithInterchainTokenFailed(address contractAddress); - error InvalidCanonicalTokenId(bytes32 expectedCanonicalTokenId); error ExpressExecuteWithInterchainTokenFailed(address contractAddress); error GatewayToken(); error TokenManagerDeploymentFailed(bytes error); error InterchainTokenDeploymentFailed(bytes error); - error SelectorUnknown(uint256 selector); + error InvalidMessageType(uint256 messageType); error InvalidMetadataVersion(uint32 version); error ExecuteWithTokenNotSupported(); error UntrustedChain(string chainName); - error InvalidExpressSelector(uint256 selector); + error InvalidExpressMessageType(uint256 messageType); - event TokenSent(bytes32 indexed tokenId, string destinationChain, bytes destinationAddress, uint256 indexed amount); - event TokenSentWithData( + event InterchainTransfer(bytes32 indexed tokenId, string destinationChain, bytes destinationAddress, uint256 indexed amount); + event InterchainTransferWithData( bytes32 indexed tokenId, string destinationChain, bytes destinationAddress, @@ -38,36 +37,34 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec address indexed sourceAddress, bytes data ); - event TokenReceived( + event InterchainTransferReceived( bytes32 indexed tokenId, string sourceChain, bytes sourceAddress, address indexed destinationAddress, uint256 indexed amount ); - event TokenReceivedWithData( + event InterchainTransferReceivedWithData( bytes32 indexed tokenId, string sourceChain, bytes sourceAddress, address indexed destinationAddress, uint256 indexed amount ); - event RemoteTokenManagerDeploymentInitialized( + event TokenManagerDeploymentStarted( bytes32 indexed tokenId, string destinationChain, - uint256 indexed gasValue, TokenManagerType indexed tokenManagerType, bytes params ); - event RemoteInterchainTokenDeploymentInitialized( + event InterchainTokenDeploymentStarted( bytes32 indexed tokenId, string tokenName, string tokenSymbol, uint8 tokenDecimals, bytes distributor, bytes operator, - string destinationChain, - uint256 indexed gasValue + string destinationChain ); event TokenManagerDeployed(bytes32 indexed tokenId, address tokenManager, TokenManagerType indexed tokenManagerType, bytes params); event InterchainTokenDeployed( @@ -78,8 +75,7 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec string symbol, uint8 decimals ); - event CustomTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); - event PausedSet(bool indexed paused, address indexed msgSender); + event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); /** * @notice Returns the address of the interchain router contract. @@ -187,7 +183,7 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec bytes calldata metadata ) external payable; - function sendTokenWithData( + function callContractWithInterchainToken( bytes32 tokenId, string calldata destinationChain, bytes calldata destinationAddress, @@ -204,7 +200,7 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec * @param amount The amount of tokens to transmit. * @param metadata The metadata associated with the transmission. */ - function transmitSendToken( + function transmitInterchainTransfer( bytes32 tokenId, address sourceAddress, string calldata destinationChain, @@ -242,8 +238,8 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_); /** - * @notice Sets the paused state of the contract. - * @param paused The boolean value indicating whether the contract is paused or not. + * @notice Allows the owner to pause/unpause the token service. + * @param paused whether to pause or unpause. */ - function setPaused(bool paused) external; + function setPauseStatus(bool paused) external; } diff --git a/contracts/token-manager/TokenManager.sol b/contracts/token-manager/TokenManager.sol index 674c9864..61ace11d 100644 --- a/contracts/token-manager/TokenManager.sol +++ b/contracts/token-manager/TokenManager.sol @@ -29,6 +29,7 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen */ constructor(address interchainTokenService_) { if (interchainTokenService_ == address(0)) revert TokenLinkerZeroAddress(); + interchainTokenService = IInterchainTokenService(interchainTokenService_); } @@ -75,18 +76,23 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen */ function setup(bytes calldata params) external override onlyProxy { bytes memory operatorBytes = abi.decode(params, (bytes)); - address operator_; + address operator; + /** * @dev Specifying an empty operator will default to the service being the operator. This makes it easy to deploy * remote standardized tokens without knowing anything about the service address at the destination. */ if (operatorBytes.length == 0) { - operator_ = address(interchainTokenService); + operator = address(interchainTokenService); } else { - operator_ = operatorBytes.toAddress(); + operator = operatorBytes.toAddress(); + + // Add flow limiter role to the service by default. The operator can remove this if they so choose. + _addAccountRoles(address(interchainTokenService), 1 << uint8(Roles.FLOW_LIMITER)); } - _addAccountRoles(operator_, (1 << uint8(Roles.FLOW_LIMITER)) | (1 << uint8(Roles.OPERATOR))); + _addAccountRoles(operator, (1 << uint8(Roles.FLOW_LIMITER)) | (1 << uint8(Roles.OPERATOR))); + _setup(params); } @@ -106,9 +112,11 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen address sender = msg.sender; amount = _takeToken(sender, amount); + + // rate limit the outgoing amount to destination _addFlowOut(amount); - interchainTokenService.transmitSendToken{ value: msg.value }( + interchainTokenService.transmitInterchainTransfer{ value: msg.value }( interchainTokenId(), sender, destinationChain, @@ -132,10 +140,14 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen bytes calldata data ) external payable virtual { address sender = msg.sender; + amount = _takeToken(sender, amount); + + // rate limit the outgoing amount to destination _addFlowOut(amount); + uint32 version = 0; - interchainTokenService.transmitSendToken{ value: msg.value }( + interchainTokenService.transmitInterchainTransfer{ value: msg.value }( interchainTokenId(), sender, destinationChain, @@ -161,8 +173,11 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen bytes calldata metadata ) external payable virtual onlyToken { amount = _takeToken(sender, amount); + + // rate limit the outgoing amount to destination _addFlowOut(amount); - interchainTokenService.transmitSendToken{ value: msg.value }( + + interchainTokenService.transmitInterchainTransfer{ value: msg.value }( interchainTokenId(), sender, destinationChain, @@ -179,6 +194,7 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen * @return the amount of token actually given, which will only be different than `amount` in cases where the token takes some on-transfer fee. */ function giveToken(address destinationAddress, uint256 amount) external onlyService returns (uint256) { + // rate limit the incoming amount from source _addFlowIn(amount); amount = _giveToken(destinationAddress, amount); return amount; @@ -191,8 +207,9 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen * @return the amount of token actually given, which will onle be differen than `amount` in cases where the token takes some on-transfer fee. */ function takeToken(address sourceAddress, uint256 amount) external onlyService returns (uint256) { - _addFlowOut(amount); amount = _takeToken(sourceAddress, amount); + // rate limit the outgoing amount to destination + _addFlowOut(amount); return amount; } @@ -209,8 +226,8 @@ abstract contract TokenManager is ITokenManager, Operatable, FlowLimit, Implemen } /** - * @notice This function adds a flow limiter for this TokenManager. Can only be called by the operator. - * @param flowLimiter the address of the new flow limiter. + * @notice This function removes a flow limiter for this TokenManager. Can only be called by the operator. + * @param flowLimiter the address of an existing flow limiter. */ function removeFlowLimiter(address flowLimiter) external onlyRole(uint8(Roles.OPERATOR)) { if (flowLimiter == address(0)) revert ZeroAddress(); diff --git a/docs/index.md b/docs/index.md index 546a2fe4..ad6ebe39 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,2510 +1,2271 @@ # Solidity API -## InterchainTokenService - -This contract is responsible for facilitating cross chain token transfers. -It (mostly) does not handle tokens, but is responsible for the messaging that needs to occur for cross chain transfers to happen. +## IMockAxelarGateway -_The only storage used here is for ExpressCalls_ +This interface is used for testing with an AxelarGateway that will arbitrarily approve calls. -### implementationLockUnlock +### NotSelf ```solidity -address implementationLockUnlock +error NotSelf() ``` -### implementationMintBurn +### NotProxy ```solidity -address implementationMintBurn +error NotProxy() ``` -### implementationMintBurnFrom +### InvalidCodeHash ```solidity -address implementationMintBurnFrom +error InvalidCodeHash() ``` -### implementationLockUnlockFee +### SetupFailed ```solidity -address implementationLockUnlockFee +error SetupFailed() ``` -### gateway +### InvalidAuthModule ```solidity -contract IAxelarGateway gateway +error InvalidAuthModule() ``` -### gasService +### InvalidTokenDeployer ```solidity -contract IAxelarGasService gasService +error InvalidTokenDeployer() ``` -### interchainAddressTracker +### InvalidAmount ```solidity -contract IInterchainAddressTracker interchainAddressTracker +error InvalidAmount() ``` -Returns the address of the interchain router contract. - -#### Return Values +### InvalidChainId -| Name | Type | Description | -| ---- | ---- | ----------- | +```solidity +error InvalidChainId() +``` -### tokenManagerDeployer +### InvalidCommands ```solidity -address tokenManagerDeployer +error InvalidCommands() ``` -Returns the address of the token manager deployer contract. - -#### Return Values +### TokenDoesNotExist -| Name | Type | Description | -| ---- | ---- | ----------- | +```solidity +error TokenDoesNotExist(string symbol) +``` -### interchainTokenDeployer +### TokenAlreadyExists ```solidity -address interchainTokenDeployer +error TokenAlreadyExists(string symbol) ``` -Returns the address of the standardized token deployer contract. - -#### Return Values +### TokenDeployFailed -| Name | Type | Description | -| ---- | ---- | ----------- | +```solidity +error TokenDeployFailed(string symbol) +``` -### chainNameHash +### TokenContractDoesNotExist ```solidity -bytes32 chainNameHash +error TokenContractDoesNotExist(address token) ``` -### PREFIX_TOKEN_ID +### BurnFailed ```solidity -bytes32 PREFIX_TOKEN_ID +error BurnFailed(string symbol) ``` -### PREFIX_INTERCHAIN_TOKEN_SALT +### MintFailed ```solidity -bytes32 PREFIX_INTERCHAIN_TOKEN_SALT +error MintFailed(string symbol) ``` -### constructor +### InvalidSetMintLimitsParams ```solidity -constructor(address tokenManagerDeployer_, address interchainTokenDeployer_, address gateway_, address gasService_, address interchainRouter_, address[] tokenManagerImplementations) public +error InvalidSetMintLimitsParams() ``` -_All of the variables passed here are stored as immutable variables._ - -#### Parameters +### ExceedMintLimit -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenManagerDeployer_ | address | the address of the TokenManagerDeployer. | -| interchainTokenDeployer_ | address | the address of the InterchainTokenDeployer. | -| gateway_ | address | the address of the AxelarGateway. | -| gasService_ | address | the address of the AxelarGasService. | -| interchainRouter_ | address | the address of the InterchainAddressTracker. | -| tokenManagerImplementations | address[] | this needs to have implementations in the order: Mint-burn, Mint-burn from, Lock-unlock, and Lock-unlock with fee. | +```solidity +error ExceedMintLimit(string symbol) +``` -### onlyRemoteService +### TokenSent ```solidity -modifier onlyRemoteService(string sourceChain, string sourceAddress) +event TokenSent(address sender, string destinationChain, string destinationAddress, string symbol, uint256 amount) ``` -This modifier is used to ensure that only a remote InterchainTokenService can _execute this one. - -#### Parameters +### ContractCall -| Name | Type | Description | -| ---- | ---- | ----------- | -| sourceChain | string | the source of the contract call. | -| sourceAddress | string | the address that the call came from. | +```solidity +event ContractCall(address sender, string destinationChain, string destinationContractAddress, bytes32 payloadHash, bytes payload) +``` -### onlyTokenManager +### ContractCallWithToken ```solidity -modifier onlyTokenManager(bytes32 tokenId) +event ContractCallWithToken(address sender, string destinationChain, string destinationContractAddress, bytes32 payloadHash, bytes payload, string symbol, uint256 amount) ``` -This modifier is used to ensure certain functions can only be called by TokenManagers. - -#### Parameters +### Executed -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the `tokenId` of the TokenManager trying to perform the call. | +```solidity +event Executed(bytes32 commandId) +``` -### contractId +### TokenDeployed ```solidity -function contractId() external pure returns (bytes32) +event TokenDeployed(string symbol, address tokenAddresses) ``` -Getter for the contract id. - -### tokenManagerAddress +### ContractCallApproved ```solidity -function tokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) +event ContractCallApproved(bytes32 commandId, string sourceChain, string sourceAddress, address contractAddress, bytes32 payloadHash, bytes32 sourceTxHash, uint256 sourceEventIndex) ``` -Calculates the address of a TokenManager from a specific tokenId. The TokenManager does not need to exist already. - -#### Parameters +### ContractCallApprovedWithMint -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId. | +```solidity +event ContractCallApprovedWithMint(bytes32 commandId, string sourceChain, string sourceAddress, address contractAddress, bytes32 payloadHash, string symbol, uint256 amount, bytes32 sourceTxHash, uint256 sourceEventIndex) +``` -#### Return Values +### TokenMintLimitUpdated -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenManagerAddress_ | address | deployment address of the TokenManager. | +```solidity +event TokenMintLimitUpdated(string symbol, uint256 limit) +``` -### validTokenManagerAddress +### OperatorshipTransferred ```solidity -function validTokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) +event OperatorshipTransferred(bytes newOperatorsData) ``` -Returns the address of a TokenManager from a specific tokenId. The TokenManager needs to exist already. - -#### Parameters +### Upgraded -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId. | +```solidity +event Upgraded(address implementation) +``` -#### Return Values +### callContract -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenManagerAddress_ | address | deployment address of the TokenManager. | +```solidity +function callContract(string destinationChain, string contractAddress, bytes payload) external +``` -### tokenAddress +### isContractCallApproved ```solidity -function tokenAddress(bytes32 tokenId) external view returns (address tokenAddress_) +function isContractCallApproved(bytes32 commandId, string sourceChain, string sourceAddress, address contractAddress, bytes32 payloadHash) external view returns (bool) ``` -Returns the address of the token that an existing tokenManager points to. - -#### Parameters +### validateContractCall -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId. | +```solidity +function validateContractCall(bytes32 commandId, string sourceChain, string sourceAddress, bytes32 payloadHash) external returns (bool) +``` -#### Return Values +### setTokenAddress -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenAddress_ | address | the address of the token. | +```solidity +function setTokenAddress(string symbol, address tokenAddress) external +``` -### interchainTokenAddress +### approveContractCall ```solidity -function interchainTokenAddress(bytes32 tokenId) public view returns (address tokenAddress_) +function approveContractCall(bytes params, bytes32 commandId) external ``` -Returns the address of the interchain token that would be deployed with a given tokenId. -The token does not need to exist. +### isCommandExecuted -#### Parameters +```solidity +function isCommandExecuted(bytes32 commandId) external view returns (bool) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId. | +### tokenAddresses -#### Return Values +```solidity +function tokenAddresses(string symbol) external view returns (address tokenAddress) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenAddress_ | address | the address of the interchain token. | +## AddressTracker -### interchainTokenId +### constructor ```solidity -function interchainTokenId(address sender, bytes32 salt) public pure returns (bytes32 tokenId) +constructor(address owner_, string chainName_, string[] trustedChainNames, string[] trustedAddresses) public ``` -Calculates the tokenId that would correspond to a custom link for a given deployer with a specified salt. -This will not depend on what chain it is called from, unlike canonical tokenIds. +### setTrustedAddress -#### Parameters +```solidity +function setTrustedAddress(string chain, string address_) external +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| sender | address | the address of the TokenManager deployer. | -| salt | bytes32 | the salt that the deployer uses for the deployment. | +_Sets the trusted address for the specified chain_ -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId that the custom TokenManager would get (or has gotten). | +| chain | string | Chain name to be trusted | +| address_ | string | Trusted address to be added for the chain | -### tokenManagerImplementation +### removeTrustedAddress ```solidity -function tokenManagerImplementation(uint256 tokenManagerType) external view returns (address) +function removeTrustedAddress(string chain) external ``` -Getter function for TokenManager implementations. This will mainly be called by TokenManagerProxies -to figure out their implementations +_Remove the trusted address of the chain._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenManagerType | uint256 | the type of the TokenManager. | +| chain | string | Chain name that should be made untrusted | -#### Return Values +## InterchainTokenExecutable -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | address | tokenManagerAddress the address of the TokenManagerImplementation. | - -### flowLimit +### NotService ```solidity -function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_) +error NotService(address caller) ``` -Getter function for the flow limit of an existing token manager with a give token ID. +### interchainTokenService -#### Parameters +```solidity +address interchainTokenService +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the token ID of the TokenManager. | +### EXECUTE_SUCCESS -#### Return Values +```solidity +bytes32 EXECUTE_SUCCESS +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowLimit_ | uint256 | the flow limit. | +### constructor -### flowOutAmount +```solidity +constructor(address interchainTokenService_) internal +``` + +### onlyService ```solidity -function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_) +modifier onlyService() ``` -Getter function for the flow out amount of an existing token manager with a give token ID. +### executeWithInterchainToken -#### Parameters +```solidity +function executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external virtual returns (bytes32) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the token ID of the TokenManager. | +This will be called after the tokens arrive to this contract -#### Return Values +_Executable should revert unless the msg.sender is the InterchainTokenService_ + +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowOutAmount_ | uint256 | the flow out amount. | +| sourceChain | string | the name of the source chain | +| sourceAddress | bytes | the address that sent the contract call | +| data | bytes | the data to be processed | +| tokenId | bytes32 | the tokenId of the token manager managing the token. | +| token | address | the address of the token. | +| amount | uint256 | the amount of token that was sent | -### flowInAmount +### _executeWithInterchainToken ```solidity -function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_) +function _executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) internal virtual ``` -Getter function for the flow in amount of an existing token manager with a give token ID. +## InterchainTokenExpressExecutable -#### Parameters +### EXPRESS_EXECUTE_SUCCESS -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | the token ID of the TokenManager. | +```solidity +bytes32 EXPRESS_EXECUTE_SUCCESS +``` -#### Return Values +### constructor -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowInAmount_ | uint256 | the flow in amount. | +```solidity +constructor(address interchainTokenService_) internal +``` -### deployTokenManager +### expressExecuteWithInterchainToken ```solidity -function deployTokenManager(bytes32 salt, string destinationChain, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params, uint256 gasValue) external payable returns (bytes32 tokenId) +function expressExecuteWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external virtual returns (bytes32) ``` -Used to deploy remote custom TokenManagers. +This will be called after the tokens arrive to this contract -_`gasValue` exists because this function can be part of a multicall involving multiple functions -that could make remote contract calls._ +_Executable should revert unless the msg.sender is the InterchainTokenService_ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| salt | bytes32 | the salt to be used. | -| destinationChain | string | the name of the chain to deploy the TokenManager and interchain token to. | -| tokenManagerType | enum ITokenManagerType.TokenManagerType | the type of TokenManager to be deployed. | -| params | bytes | the params that will be used to initialize the TokenManager. | -| gasValue | uint256 | the amount of native tokens to be used to pay for gas for the remote deployment. At least the amount specified needs to be passed to the call | +| sourceChain | string | the name of the source chain | +| sourceAddress | bytes | the address that sent the contract call | +| data | bytes | the data to be processed | +| tokenId | bytes32 | the token id of the token manager managing the token. | +| token | address | the address of the token. | +| amount | uint256 | the amount of token that was sent | -### deployInterchainToken +## InterchainTokenService -```solidity -function deployInterchainToken(bytes32 salt, string destinationChain, string name, string symbol, uint8 decimals, bytes distributor, bytes operator, uint256 gasValue) external payable -``` +This contract is responsible for facilitating cross chain token transfers. +It (mostly) does not handle tokens, but is responsible for the messaging that needs to occur for cross chain transfers to happen. -Used to deploy a interchain token alongside a TokenManager in another chain. If the `distributor` is empty -bytes then a mint/burn TokenManager is used. Otherwise a lock/unlock TokenManager is used. +_The only storage used here is for ExpressCalls_ -_`gasValue` exists because this function can be part of a multicall involving multiple functions that could make remote contract calls._ +### gateway -#### Parameters +```solidity +contract IAxelarGateway gateway +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| salt | bytes32 | the salt to be used. | -| destinationChain | string | the name of the destination chain to deploy to. | -| name | string | the name of the token to be deployed. | -| symbol | string | the symbol of the token to be deployed. | -| decimals | uint8 | the decimals of the token to be deployed. | -| distributor | bytes | the address that will be able to mint and burn the deployed token. | -| operator | bytes | | -| gasValue | uint256 | the amount of native tokens to be used to pay for gas for the remote deployment. At least the amount specified needs to be passed to the call | +### gasService -### contractCallValue +```solidity +contract IAxelarGasService gasService +``` + +### chainNameHash ```solidity -function contractCallValue(string sourceChain, string sourceAddress, bytes payload) public view virtual returns (address, uint256) +bytes32 chainNameHash ``` -_Returns the value (token address and amount) associated with a contract call_ +### interchainTokenDeployer -#### Parameters +```solidity +address interchainTokenDeployer +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| sourceChain | string | The source blockchain. | -| sourceAddress | string | The source address. | -| payload | bytes | The payload data. | +Returns the address of the standardized token deployer contract. #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | address | | -| [1] | uint256 | | -### expressExecute +### tokenManagerDeployer ```solidity -function expressExecute(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload) external payable +address tokenManagerDeployer ``` -Express executes a contract call. +Returns the address of the token manager deployer contract. -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| commandId | bytes32 | The commandId for the contractCall. | -| sourceChain | string | The source chain. | -| sourceAddress | string | The source address. | -| payload | bytes | The payload data. | -### _expressExecute +### implementationLockUnlock ```solidity -function _expressExecute(string sourceChain, bytes payload) internal +address implementationLockUnlock ``` -Uses the caller's tokens to fullfill a sendCall ahead of time. Use this only if you have detected an outgoing -interchainTransfer that matches the parameters passed here. +_Token manager implementation addresses_ -_This is not to be used with fee on transfer tokens as it will incur losses for the express caller._ +### implementationLockUnlockFee -#### Parameters +```solidity +address implementationLockUnlockFee +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| sourceChain | string | the name of the chain where the interchainTransfer originated from. | -| payload | bytes | the payload of the receive token | +### implementationMintBurn -### interchainTransfer +```solidity +address implementationMintBurn +``` + +### implementationMintBurnFrom ```solidity -function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable +address implementationMintBurnFrom ``` -Transfer a token interchain. +### interchainAddressTracker -#### Parameters +```solidity +contract IInterchainAddressTracker interchainAddressTracker +``` + +Returns the address of the interchain router contract. + +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId for the token link. | -| destinationChain | string | the name of the chain to send the token to. | -| destinationAddress | bytes | the recipient of the interchain transfer. | -| amount | uint256 | the amount of token to give. | -| metadata | bytes | the data to be passed to the destination. If provided with a bytes4(0) prefix, it'll execute the destination contract. | -### sendTokenWithData +### PREFIX_TOKEN_ID + +```solidity +bytes32 PREFIX_TOKEN_ID +``` + +### PREFIX_INTERCHAIN_TOKEN_SALT ```solidity -function sendTokenWithData(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable +bytes32 PREFIX_INTERCHAIN_TOKEN_SALT ``` -### transmitSendToken +### constructor ```solidity -function transmitSendToken(bytes32 tokenId, address sourceAddress, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable +constructor(address tokenManagerDeployer_, address interchainTokenDeployer_, address gateway_, address gasService_, address interchainAddressTracker_, address[] tokenManagerImplementations) public ``` -Transmit a sendTokenWithData for the given tokenId. Only callable by a token manager. +_All of the variables passed here are stored as immutable variables._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId of the TokenManager (which must be the msg.sender). | -| sourceAddress | address | the address where the token is coming from, which will also be used for reimbursement of gas. | -| destinationChain | string | the name of the chain to send tokens to. | -| destinationAddress | bytes | the destinationAddress for the interchainTransfer. | -| amount | uint256 | the amount of token to give. | -| metadata | bytes | the data to be passed to the destination. | +| tokenManagerDeployer_ | address | the address of the TokenManagerDeployer. | +| interchainTokenDeployer_ | address | the address of the InterchainTokenDeployer. | +| gateway_ | address | the address of the AxelarGateway. | +| gasService_ | address | the address of the AxelarGasService. | +| interchainAddressTracker_ | address | the address of the InterchainAddressTracker. | +| tokenManagerImplementations | address[] | this needs to have implementations in the order: Mint-burn, Mint-burn from, Lock-unlock, and Lock-unlock with fee. | -### setFlowLimits +### onlyRemoteService ```solidity -function setFlowLimits(bytes32[] tokenIds, uint256[] flowLimits) external +modifier onlyRemoteService(string sourceChain, string sourceAddress) ``` -Used to set a flow limit for a token manager that has the service as its operator. +This modifier is used to ensure that only a remote InterchainTokenService can _execute this one. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenIds | bytes32[] | an array of the token Ids of the tokenManagers to set the flow limit of. | -| flowLimits | uint256[] | the flowLimits to set | +| sourceChain | string | the source of the contract call. | +| sourceAddress | string | the address that the call came from. | -### setPaused +### onlyTokenManager ```solidity -function setPaused(bool paused) external +modifier onlyTokenManager(bytes32 tokenId) ``` -Used to pause the entire service. +This modifier is used to ensure certain functions can only be called by TokenManagers. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| paused | bool | what value to set paused to. | +| tokenId | bytes32 | the `tokenId` of the TokenManager trying to perform the call. | -### _setup +### contractId ```solidity -function _setup(bytes params) internal +function contractId() external pure returns (bytes32) ``` -### _sanitizeTokenManagerImplementation - -```solidity -function _sanitizeTokenManagerImplementation(address[] tokenManagerImplementations, enum ITokenManagerType.TokenManagerType tokenManagerType) internal pure returns (address implementation_) -``` +Getter for the contract id. -### execute +### tokenManagerAddress ```solidity -function execute(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload) external +function tokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) ``` -Executes operations based on the payload and selector. +Calculates the address of a TokenManager from a specific tokenId. The TokenManager does not need to exist already. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| commandId | bytes32 | | -| sourceChain | string | The chain where the transaction originates from | -| sourceAddress | string | The address of the remote ITS where the transaction originates from | -| payload | bytes | The encoded data payload for the transaction | - -### contractCallWithTokenValue +| tokenId | bytes32 | the tokenId. | -```solidity -function contractCallWithTokenValue(string, string, bytes, string, uint256) public view virtual returns (address, uint256) -``` +#### Return Values -### expressExecuteWithToken - -```solidity -function expressExecuteWithToken(bytes32, string, string, bytes, string, uint256) external payable -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenManagerAddress_ | address | deployment address of the TokenManager. | -### executeWithToken +### validTokenManagerAddress ```solidity -function executeWithToken(bytes32, string, string, bytes, string, uint256) external pure +function validTokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) ``` -### _processReceiveTokenPayload +Returns the address of a TokenManager from a specific tokenId. The TokenManager needs to exist already. -```solidity -function _processReceiveTokenPayload(address expressExecutor, string sourceChain, bytes payload, uint256 selector) internal -``` +#### Parameters -Processes the payload data for a send token call +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | the tokenId. | -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| expressExecutor | address | | -| sourceChain | string | The chain where the transaction originates from | -| payload | bytes | The encoded data payload to be processed | -| selector | uint256 | | +| tokenManagerAddress_ | address | deployment address of the TokenManager. | -### _processDeployTokenManagerPayload +### tokenAddress ```solidity -function _processDeployTokenManagerPayload(bytes payload) internal +function tokenAddress(bytes32 tokenId) external view returns (address tokenAddress_) ``` -Processes a deploy token manager payload. +Returns the address of the token that an existing tokenManager points to. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| payload | bytes | The encoded data payload to be processed | - -### _processDeployInterchainTokenPayload - -```solidity -function _processDeployInterchainTokenPayload(bytes payload) internal -``` - -Process a deploy interchain token and manager payload. +| tokenId | bytes32 | the tokenId. | -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| payload | bytes | The encoded data payload to be processed | +| tokenAddress_ | address | the address of the token. | -### _callContract +### interchainTokenAddress ```solidity -function _callContract(string destinationChain, bytes payload, uint256 gasValue) internal +function interchainTokenAddress(bytes32 tokenId) public view returns (address tokenAddress_) ``` -Calls a contract on a specific destination chain with the given payload +Returns the address of the interchain token that would be deployed with a given tokenId. +The token does not need to exist. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| destinationChain | string | The target chain where the contract will be called | -| payload | bytes | The data payload for the transaction | -| gasValue | uint256 | The amount of gas to be paid for the transaction | +| tokenId | bytes32 | the tokenId. | -### _validateToken +#### Return Values -```solidity -function _validateToken(address tokenAddress_) internal view returns (string name, string symbol, uint8 decimals) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress_ | address | the address of the interchain token. | -### _deployRemoteTokenManager +### interchainTokenId ```solidity -function _deployRemoteTokenManager(bytes32 tokenId, string destinationChain, uint256 gasValue, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) internal +function interchainTokenId(address sender, bytes32 salt) public pure returns (bytes32 tokenId) ``` -Deploys a token manager on a destination chain. +Calculates the tokenId that would correspond to a link for a given deployer with a specified salt. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The ID of the token | -| destinationChain | string | The chain where the token manager will be deployed | -| gasValue | uint256 | The amount of gas to be paid for the transaction | -| tokenManagerType | enum ITokenManagerType.TokenManagerType | The type of token manager to be deployed | -| params | bytes | Additional parameters for the token manager deployment | - -### _deployRemoteInterchainToken - -```solidity -function _deployRemoteInterchainToken(bytes32 tokenId, string name, string symbol, uint8 decimals, bytes distributor, bytes operator, string destinationChain, uint256 gasValue) internal -``` - -Deploys a interchain token on a destination chain. +| sender | address | the address of the TokenManager deployer. | +| salt | bytes32 | the salt that the deployer uses for the deployment. | -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The ID of the token | -| name | string | The name of the token | -| symbol | string | The symbol of the token | -| decimals | uint8 | The number of decimals of the token | -| distributor | bytes | The distributor address for the token | -| operator | bytes | | -| destinationChain | string | The destination chain where the token will be deployed | -| gasValue | uint256 | The amount of gas to be paid for the transaction | +| tokenId | bytes32 | the tokenId that the custom TokenManager would get (or has gotten). | -### _deployTokenManager +### tokenManagerImplementation ```solidity -function _deployTokenManager(bytes32 tokenId, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) internal +function tokenManagerImplementation(uint256 tokenManagerType) external view returns (address) ``` -Deploys a token manager +Getter function for TokenManager implementations. This will mainly be called by TokenManagerProxies +to figure out their implementations #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The ID of the token | -| tokenManagerType | enum ITokenManagerType.TokenManagerType | The type of the token manager to be deployed | -| params | bytes | Additional parameters for the token manager deployment | +| tokenManagerType | uint256 | the type of the TokenManager. | -### _getInterchainTokenSalt +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | address | tokenManagerAddress the address of the TokenManagerImplementation. | + +### flowLimit ```solidity -function _getInterchainTokenSalt(bytes32 tokenId) internal pure returns (bytes32 salt) +function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_) ``` -Compute the salt for a interchain token deployment. +Getter function for the flow limit of an existing token manager with a give token ID. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The ID of the token | +| tokenId | bytes32 | the token ID of the TokenManager. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| salt | bytes32 | The computed salt for the token deployment | +| flowLimit_ | uint256 | the flow limit. | -### _deployInterchainToken +### flowOutAmount ```solidity -function _deployInterchainToken(bytes32 tokenId, bytes distributorBytes, string name, string symbol, uint8 decimals) internal returns (address tokenAddress_) +function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_) ``` -Deploys a interchain token. +Getter function for the flow out amount of an existing token manager with a give token ID. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The ID of the token | -| distributorBytes | bytes | The distributor address for the token | -| name | string | The name of the token | -| symbol | string | The symbol of the token | -| decimals | uint8 | The number of decimals of the token | +| tokenId | bytes32 | the token ID of the TokenManager. | -### _decodeMetadata +#### Return Values -```solidity -function _decodeMetadata(bytes metadata) internal pure returns (uint32 version, bytes data) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowOutAmount_ | uint256 | the flow out amount. | -### _transmitSendToken +### flowInAmount ```solidity -function _transmitSendToken(bytes32 tokenId, address sourceAddress, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) internal +function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_) ``` -Transmit a sendTokenWithData for the given tokenId. Only callable by a token manager. +Getter function for the flow in amount of an existing token manager with a give token ID. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | the tokenId of the TokenManager (which must be the msg.sender). | -| sourceAddress | address | the address where the token is coming from, which will also be used for reimburment of gas. | -| destinationChain | string | the name of the chain to send tokens to. | -| destinationAddress | bytes | the destinationAddress for the interchainTransfer. | -| amount | uint256 | the amount of token to give. | -| metadata | bytes | the data to be passed to the destiantion. | +| tokenId | bytes32 | the token ID of the TokenManager. | -## IDistributable +#### Return Values -### transferDistributorship +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowInAmount_ | uint256 | the flow in amount. | + +### deployTokenManager ```solidity -function transferDistributorship(address distributor_) external +function deployTokenManager(bytes32 salt, string destinationChain, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params, uint256 gasValue) external payable returns (bytes32 tokenId) ``` -Change the distributor of the contract +Used to deploy remote custom TokenManagers. -_Can only be called by the current distributor_ +_`gasValue` exists because this function can be part of a multicall involving multiple functions +that could make remote contract calls._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| distributor_ | address | The address of the new distributor | +| salt | bytes32 | the salt to be used. | +| destinationChain | string | the name of the chain to deploy the TokenManager and interchain token to. | +| tokenManagerType | enum ITokenManagerType.TokenManagerType | the type of TokenManager to be deployed. | +| params | bytes | the params that will be used to initialize the TokenManager. | +| gasValue | uint256 | the amount of native tokens to be used to pay for gas for the remote deployment. At least the amount specified needs to be passed to the call | -### proposeDistributorship +### deployInterchainToken ```solidity -function proposeDistributorship(address distributor_) external +function deployInterchainToken(bytes32 salt, string destinationChain, string name, string symbol, uint8 decimals, bytes distributor, bytes operator, uint256 gasValue) external payable ``` -Proposed a change of the distributor of the contract +Used to deploy a interchain token alongside a TokenManager in another chain. If the `distributor` is empty +bytes then a mint/burn TokenManager is used. Otherwise a lock/unlock TokenManager is used. -_Can only be called by the current distributor_ +_`gasValue` exists because this function can be part of a multicall involving multiple functions that could make remote contract calls._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| distributor_ | address | The address of the new distributor | - -### acceptDistributorship - -```solidity -function acceptDistributorship(address fromDistributor) external -``` - -Accept a change of the distributor of the contract - -_Can only be called by the proposed distributor_ +| salt | bytes32 | the salt to be used. | +| destinationChain | string | the name of the destination chain to deploy to. | +| name | string | the name of the token to be deployed. | +| symbol | string | the symbol of the token to be deployed. | +| decimals | uint8 | the decimals of the token to be deployed. | +| distributor | bytes | the address that will be able to mint and burn the deployed token. | +| operator | bytes | | +| gasValue | uint256 | the amount of native tokens to be used to pay for gas for the remote deployment. At least the amount specified needs to be passed to the call | -### isDistributor +### contractCallValue ```solidity -function isDistributor(address addr) external view returns (bool) +function contractCallValue(string sourceChain, string sourceAddress, bytes payload) public view virtual returns (address, uint256) ``` -Query if an address is a distributor +_Returns the value (token address and amount) associated with a contract call_ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| addr | address | the address to query for | +| sourceChain | string | The source blockchain. | +| sourceAddress | string | The source address. | +| payload | bytes | The payload data. | -## IERC20BurnableFrom +#### Return Values -_Interface of the ERC20 standard as defined in the EIP._ +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | address | | +| [1] | uint256 | | -### burnFrom +### expressExecute ```solidity -function burnFrom(address from, uint256 amount) external +function expressExecute(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload) external payable ``` -Function to burn tokens -Requires the caller to have allowance for `amount` on `from` - -_Can only be called by the distributor address._ +Express executes a contract call. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| from | address | The address that will have its tokens burnt | -| amount | uint256 | The amount of tokens to burn | - -## IERC20MintableBurnable - -_Interface of the ERC20 standard as defined in the EIP._ +| commandId | bytes32 | The commandId for the contractCall. | +| sourceChain | string | The source chain. | +| sourceAddress | string | The source address. | +| payload | bytes | The payload data. | -### mint +### _expressExecute ```solidity -function mint(address to, uint256 amount) external +function _expressExecute(string sourceChain, bytes payload) internal ``` -Function to mint new tokens +Uses the caller's tokens to fullfill a sendCall ahead of time. Use this only if you have detected an outgoing +interchainTransfer that matches the parameters passed here. -_Can only be called by the distributor address._ +_This is not to be used with fee on transfer tokens as it will incur losses for the express caller._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| to | address | The address that will receive the minted tokens | -| amount | uint256 | The amount of tokens to mint | +| sourceChain | string | the name of the chain where the interchainTransfer originated from. | +| payload | bytes | the payload of the receive token | -### burn +### interchainTransfer ```solidity -function burn(address from, uint256 amount) external +function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable ``` -Function to burn tokens - -_Can only be called by the distributor address._ +Transfer a token interchain. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| from | address | The address that will have its tokens burnt | -| amount | uint256 | The amount of tokens to burn | - -## IERC20Named - -_Interface of the ERC20 standard as defined in the EIP._ +| tokenId | bytes32 | the tokenId for the token link. | +| destinationChain | string | the name of the chain to send the token to. | +| destinationAddress | bytes | the recipient of the interchain transfer. | +| amount | uint256 | the amount of token to give. | +| metadata | bytes | the data to be passed to the destination. If provided with a bytes4(0) prefix, it'll execute the destination contract. | -### name +### callContractWithInterchainToken ```solidity -function name() external view returns (string) +function callContractWithInterchainToken(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable ``` -Getter for the name of the token - -### symbol +### transmitInterchainTransfer ```solidity -function symbol() external view returns (string) +function transmitInterchainTransfer(bytes32 tokenId, address sourceAddress, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable ``` -Getter for the symbol of the token - -### decimals - -```solidity -function decimals() external view returns (uint8) -``` +Transmit an interchain transfer for the given tokenId. Only callable by a token manager. -Getter for the decimals of the token +#### Parameters -## IFlowLimit +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | the tokenId of the TokenManager (which must be the msg.sender). | +| sourceAddress | address | the address where the token is coming from, which will also be used for reimbursement of gas. | +| destinationChain | string | the name of the chain to send tokens to. | +| destinationAddress | bytes | the destinationAddress for the interchainTransfer. | +| amount | uint256 | the amount of token to give. | +| metadata | bytes | the data to be passed to the destination. | -### FlowLimitExceeded +### setFlowLimits ```solidity -error FlowLimitExceeded(uint256 limit, uint256 flowAmount) +function setFlowLimits(bytes32[] tokenIds, uint256[] flowLimits) external ``` -### FlowLimitSet +Used to set a flow limit for a token manager that has the service as its operator. -```solidity -event FlowLimitSet(bytes32 tokenId, address operator, uint256 flowLimit_) -``` +#### Parameters -### flowLimit +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenIds | bytes32[] | an array of the token Ids of the tokenManagers to set the flow limit of. | +| flowLimits | uint256[] | the flowLimits to set | + +### setPauseStatus ```solidity -function flowLimit() external view returns (uint256 flowLimit_) +function setPauseStatus(bool paused) external ``` -Returns the current flow limit +Allows the owner to pause/unpause the token service. -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowLimit_ | uint256 | The current flow limit value | +| paused | bool | whether to pause or unpause. | -### flowOutAmount +### _setup ```solidity -function flowOutAmount() external view returns (uint256 flowOutAmount_) +function _setup(bytes params) internal ``` -Returns the current flow out amount - -#### Return Values +### _sanitizeTokenManagerImplementation -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowOutAmount_ | uint256 | The current flow out amount | +```solidity +function _sanitizeTokenManagerImplementation(address[] tokenManagerImplementations, enum ITokenManagerType.TokenManagerType tokenManagerType) internal pure returns (address implementation_) +``` -### flowInAmount +### execute ```solidity -function flowInAmount() external view returns (uint256 flowInAmount_) +function execute(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload) external ``` -Returns the current flow in amount +Executes operations based on the payload and messageType. -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowInAmount_ | uint256 | The current flow in amount | +| commandId | bytes32 | | +| sourceChain | string | The chain where the transaction originates from | +| sourceAddress | string | The address of the remote ITS where the transaction originates from | +| payload | bytes | The encoded data payload for the transaction | -## IImplementation +### contractCallWithTokenValue -### NotProxy +```solidity +function contractCallWithTokenValue(string, string, bytes, string, uint256) public view virtual returns (address, uint256) +``` + +### expressExecuteWithToken ```solidity -error NotProxy() +function expressExecuteWithToken(bytes32, string, string, bytes, string, uint256) external payable ``` -### setup +### executeWithToken ```solidity -function setup(bytes params) external +function executeWithToken(bytes32, string, string, bytes, string, uint256) external pure ``` -Called by the proxy to setup itself. +### _processInterchainTransferPayload -_This should be hidden by the proxy._ +```solidity +function _processInterchainTransferPayload(address expressExecutor, string sourceChain, bytes payload, uint256 messageType) internal +``` + +Processes the payload data for a send token call #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| params | bytes | the data to be used for the initialization. | - -## IInterchainToken - -_Interface of the ERC20 standard as defined in the EIP._ +| expressExecutor | address | | +| sourceChain | string | The chain where the transaction originates from | +| payload | bytes | The encoded data payload to be processed | +| messageType | uint256 | | -### tokenManager +### _processDeployTokenManagerPayload ```solidity -function tokenManager() external view returns (contract ITokenManager tokenManager_) +function _processDeployTokenManagerPayload(bytes payload) internal ``` -Getter for the tokenManager used for this token. - -_Needs to be overwitten._ +Processes a deploy token manager payload. -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenManager_ | contract ITokenManager | the TokenManager called to facilitate cross chain transfers. | +| payload | bytes | The encoded data payload to be processed | -### interchainTransfer +### _processDeployInterchainTokenPayload ```solidity -function interchainTransfer(string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable +function _processDeployInterchainTokenPayload(bytes payload) internal ``` -Implementation of the interchainTransfer method - -_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. -A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ +Process a deploy interchain token and manager payload. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| destinationChain | string | The destination chain identifier. | -| recipient | bytes | The bytes representation of the address of the recipient. | -| amount | uint256 | The amount of token to be transferred. | -| metadata | bytes | Either empty, to just facilitate an interchain transfer, or the data can be passed for an interchain contract call with transfer as per semantics defined by the token service. | +| payload | bytes | The encoded data payload to be processed | -### interchainTransferFrom +### _callContract ```solidity -function interchainTransferFrom(address sender, string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable +function _callContract(string destinationChain, bytes payload, uint256 gasValue) internal ``` -Implementation of the interchainTransferFrom method - -_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. -A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ +Calls a contract on a specific destination chain with the given payload #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| sender | address | the sender of the tokens. They need to have approved `msg.sender` before this is called. | -| destinationChain | string | the string representation of the destination chain. | -| recipient | bytes | the bytes representation of the address of the recipient. | -| amount | uint256 | the amount of token to be transferred. | -| metadata | bytes | either empty, to just facilitate a cross-chain transfer, or the data to be passed to a cross-chain contract call and transfer. | - -## IInterchainTokenDeployer - -This contract is used to deploy new instances of the StandardizedTokenProxy contract. +| destinationChain | string | The target chain where the contract will be called | +| payload | bytes | The data payload for the transaction | +| gasValue | uint256 | The amount of gas to be paid for the transaction | -### AddressZero +### _validateToken ```solidity -error AddressZero() +function _validateToken(address tokenAddress_) internal view returns (string name, string symbol, uint8 decimals) ``` -### TokenDeploymentFailed +### _deployRemoteTokenManager ```solidity -error TokenDeploymentFailed() +function _deployRemoteTokenManager(bytes32 tokenId, string destinationChain, uint256 gasValue, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) internal ``` -### implementationAddress +Deploys a token manager on a destination chain. -```solidity -function implementationAddress() external view returns (address) -``` +#### Parameters -Returns the standardized token implementation address +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | The ID of the token | +| destinationChain | string | The chain where the token manager will be deployed | +| gasValue | uint256 | The amount of gas to be paid for the transaction | +| tokenManagerType | enum ITokenManagerType.TokenManagerType | The type of token manager to be deployed | +| params | bytes | Additional parameters for the token manager deployment | -### deployedAddress +### _deployRemoteInterchainToken ```solidity -function deployedAddress(bytes32 salt) external view returns (address tokenAddress) +function _deployRemoteInterchainToken(bytes32 tokenId, string name, string symbol, uint8 decimals, bytes distributor, bytes operator, string destinationChain, uint256 gasValue) internal ``` -Returns the standardized token deployment address. +Deploys a interchain token on a destination chain. -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenAddress | address | the token address. | +| tokenId | bytes32 | The ID of the token | +| name | string | The name of the token | +| symbol | string | The symbol of the token | +| decimals | uint8 | The number of decimals of the token | +| distributor | bytes | The distributor address for the token | +| operator | bytes | | +| destinationChain | string | The destination chain where the token will be deployed | +| gasValue | uint256 | The amount of gas to be paid for the transaction | -### deployInterchainToken +### _deployTokenManager ```solidity -function deployInterchainToken(bytes32 salt, address tokenManager, address distributor, string name, string symbol, uint8 decimals) external payable returns (address tokenAddress) +function _deployTokenManager(bytes32 tokenId, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) internal ``` -Deploys a new instance of the StandardizedTokenProxy contract +Deploys a token manager #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| salt | bytes32 | The salt used by Create3Deployer | -| tokenManager | address | Address of the token manager | -| distributor | address | Address of the distributor | -| name | string | Name of the token | -| symbol | string | Symbol of the token | -| decimals | uint8 | Decimals of the token | - -#### Return Values - -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenAddress | address | Address of the deployed token | - -## IInterchainTokenExecutable - -Implement this to accept calls from the InterchainTokenService. +| tokenId | bytes32 | The ID of the token | +| tokenManagerType | enum ITokenManagerType.TokenManagerType | The type of the token manager to be deployed | +| params | bytes | Additional parameters for the token manager deployment | -### executeWithInterchainToken +### _getInterchainTokenSalt ```solidity -function executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external returns (bytes32) +function _getInterchainTokenSalt(bytes32 tokenId) internal pure returns (bytes32 salt) ``` -This will be called after the tokens arrive to this contract - -_Executable should revert unless the msg.sender is the InterchainTokenService_ +Compute the salt for a interchain token deployment. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| sourceChain | string | the name of the source chain | -| sourceAddress | bytes | the address that sent the contract call | -| data | bytes | the data to be processed | -| tokenId | bytes32 | the tokenId of the token manager managing the token. | -| token | address | the address of the token. | -| amount | uint256 | the amount of token that was sent | +| tokenId | bytes32 | The ID of the token | -## IInterchainTokenExpressExecutable +#### Return Values -Implement this to accept express calls from the InterchainTokenService. +| Name | Type | Description | +| ---- | ---- | ----------- | +| salt | bytes32 | The computed salt for the token deployment | -### expressExecuteWithInterchainToken +### _deployInterchainToken ```solidity -function expressExecuteWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external returns (bytes32) +function _deployInterchainToken(bytes32 tokenId, bytes distributorBytes, string name, string symbol, uint8 decimals) internal returns (address tokenAddress_) ``` -This will be called after the tokens arrive to this contract - -_Executable should revert unless the msg.sender is the InterchainTokenService_ +Deploys a interchain token. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| sourceChain | string | the name of the source chain | -| sourceAddress | bytes | the address that sent the contract call | -| data | bytes | the data to be processed | -| tokenId | bytes32 | the token id of the token manager managing the token. | -| token | address | the address of the token. | -| amount | uint256 | the amount of token that was sent | - -## IInterchainTokenService +| tokenId | bytes32 | The ID of the token | +| distributorBytes | bytes | The distributor address for the token | +| name | string | The name of the token | +| symbol | string | The symbol of the token | +| decimals | uint8 | The number of decimals of the token | -### ZeroAddress +### _decodeMetadata ```solidity -error ZeroAddress() +function _decodeMetadata(bytes metadata) internal pure returns (uint32 version, bytes data) ``` -### LengthMismatch +### _transmitInterchainTransfer ```solidity -error LengthMismatch() +function _transmitInterchainTransfer(bytes32 tokenId, address sourceAddress, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) internal ``` -### InvalidTokenManagerImplementationType - -```solidity -error InvalidTokenManagerImplementationType(address implementation) -``` +Transmit a callContractWithInterchainToken for the given tokenId. Only callable by a token manager. -### NotRemoteService +#### Parameters -```solidity -error NotRemoteService() -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | the tokenId of the TokenManager (which must be the msg.sender). | +| sourceAddress | address | the address where the token is coming from, which will also be used for reimburment of gas. | +| destinationChain | string | the name of the chain to send tokens to. | +| destinationAddress | bytes | the destinationAddress for the interchainTransfer. | +| amount | uint256 | the amount of token to give. | +| metadata | bytes | the data to be passed to the destination. | -### TokenManagerDoesNotExist +## InterchainToken -```solidity -error TokenManagerDoesNotExist(bytes32 tokenId) -``` +The implementation ERC20 can be done in any way, however this example assumes that an _approve internal function exists +that can be used to create approvals, and that `allowance` is a mapping. -### NotTokenManager +### tokenManager ```solidity -error NotTokenManager(address caller, address tokenManager) +function tokenManager() public view virtual returns (contract ITokenManager tokenManager_) ``` -### ExecuteWithInterchainTokenFailed +Getter for the tokenManager used for this token. -```solidity -error ExecuteWithInterchainTokenFailed(address contractAddress) -``` +_Needs to be overwritten._ -### InvalidCanonicalTokenId +#### Return Values -```solidity -error InvalidCanonicalTokenId(bytes32 expectedCanonicalTokenId) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenManager_ | contract ITokenManager | the TokenManager called to facilitate cross chain transfers. | -### ExpressExecuteWithInterchainTokenFailed +### interchainTransfer ```solidity -error ExpressExecuteWithInterchainTokenFailed(address contractAddress) +function interchainTransfer(string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable ``` -### GatewayToken +Implementation of the interchainTransfer method -```solidity -error GatewayToken() -``` +_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. +A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ -### TokenManagerDeploymentFailed +#### Parameters -```solidity -error TokenManagerDeploymentFailed(bytes error) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| destinationChain | string | The destination chain identifier. | +| recipient | bytes | The bytes representation of the address of the recipient. | +| amount | uint256 | The amount of token to be transferred. | +| metadata | bytes | Either empty, to just facilitate an interchain transfer, or the data can be passed for an interchain contract call with transfer as per semantics defined by the token service. | -### InterchainTokenDeploymentFailed +### interchainTransferFrom ```solidity -error InterchainTokenDeploymentFailed(bytes error) +function interchainTransferFrom(address sender, string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable ``` -### SelectorUnknown +Implementation of the interchainTransferFrom method -```solidity -error SelectorUnknown(uint256 selector) -``` +_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. +A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ -### InvalidMetadataVersion +#### Parameters -```solidity -error InvalidMetadataVersion(uint32 version) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| sender | address | the sender of the tokens. They need to have approved `msg.sender` before this is called. | +| destinationChain | string | the string representation of the destination chain. | +| recipient | bytes | the bytes representation of the address of the recipient. | +| amount | uint256 | the amount of token to be transferred. | +| metadata | bytes | either empty, to just facilitate a cross-chain transfer, or the data to be passed to a cross-chain contract call and transfer. | -### ExecuteWithTokenNotSupported +### _beforeInterchainTransfer ```solidity -error ExecuteWithTokenNotSupported() +function _beforeInterchainTransfer(address from, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) internal virtual ``` -### UntrustedChain +A method to be overwritten that will be called before an interchain transfer. You can approve the tokenManager here if you need and want to, to allow users for a 1-call transfer in case of a lock-unlock token manager. -```solidity -error UntrustedChain(string chainName) -``` +#### Parameters -### InvalidExpressSelector +| Name | Type | Description | +| ---- | ---- | ----------- | +| from | address | the sender of the tokens. They need to have approved `msg.sender` before this is called. | +| destinationChain | string | the string representation of the destination chain. | +| destinationAddress | bytes | the bytes representation of the address of the recipient. | +| amount | uint256 | the amount of token to be transferred. | +| metadata | bytes | either empty, to just facilitate a cross-chain transfer, or the data to be passed to a cross-chain contract call and transfer. | -```solidity -error InvalidExpressSelector(uint256 selector) -``` +## IAddressTracker -### TokenSent +### setTrustedAddress ```solidity -event TokenSent(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount) +function setTrustedAddress(string chain, string address_) external ``` -### TokenSentWithData - -```solidity -event TokenSentWithData(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, address sourceAddress, bytes data) -``` +_Sets the trusted address for the specified chain_ -### TokenReceived +#### Parameters -```solidity -event TokenReceived(bytes32 tokenId, string sourceChain, bytes sourceAddress, address destinationAddress, uint256 amount) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| chain | string | Chain name to be trusted | +| address_ | string | Trusted address to be added for the chain | -### TokenReceivedWithData +### removeTrustedAddress ```solidity -event TokenReceivedWithData(bytes32 tokenId, string sourceChain, bytes sourceAddress, address destinationAddress, uint256 amount) +function removeTrustedAddress(string chain) external ``` -### RemoteTokenManagerDeploymentInitialized +_Remove the trusted address of the chain._ -```solidity -event RemoteTokenManagerDeploymentInitialized(bytes32 tokenId, string destinationChain, uint256 gasValue, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) -``` +#### Parameters -### RemoteInterchainTokenDeploymentInitialized +| Name | Type | Description | +| ---- | ---- | ----------- | +| chain | string | Chain name that should be made untrusted | -```solidity -event RemoteInterchainTokenDeploymentInitialized(bytes32 tokenId, string tokenName, string tokenSymbol, uint8 tokenDecimals, bytes distributor, bytes operator, string destinationChain, uint256 gasValue) -``` +## IDistributable -### TokenManagerDeployed +### transferDistributorship ```solidity -event TokenManagerDeployed(bytes32 tokenId, address tokenManager, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) +function transferDistributorship(address distributor_) external ``` -### InterchainTokenDeployed +Change the distributor of the contract -```solidity -event InterchainTokenDeployed(bytes32 tokenId, address tokenAddress, address distributor, string name, string symbol, uint8 decimals) -``` +_Can only be called by the current distributor_ -### CustomTokenIdClaimed +#### Parameters -```solidity -event CustomTokenIdClaimed(bytes32 tokenId, address deployer, bytes32 salt) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| distributor_ | address | The address of the new distributor | -### PausedSet +### proposeDistributorship ```solidity -event PausedSet(bool paused, address msgSender) +function proposeDistributorship(address distributor_) external ``` -### interchainAddressTracker - -```solidity -function interchainAddressTracker() external view returns (contract IInterchainAddressTracker interchainAddressTracker_) -``` +Proposed a change of the distributor of the contract -Returns the address of the interchain router contract. +_Can only be called by the current distributor_ -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| interchainAddressTracker_ | contract IInterchainAddressTracker | The interchainAddressTracker. | +| distributor_ | address | The address of the new distributor | -### tokenManagerDeployer +### acceptDistributorship ```solidity -function tokenManagerDeployer() external view returns (address tokenManagerDeployerAddress) +function acceptDistributorship(address fromDistributor) external ``` -Returns the address of the token manager deployer contract. - -#### Return Values +Accept a change of the distributor of the contract -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenManagerDeployerAddress | address | The address of the token manager deployer contract. | +_Can only be called by the proposed distributor_ -### interchainTokenDeployer +### isDistributor ```solidity -function interchainTokenDeployer() external view returns (address interchainTokenDeployerAddress) +function isDistributor(address addr) external view returns (bool) ``` -Returns the address of the standardized token deployer contract. +Query if an address is a distributor -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| interchainTokenDeployerAddress | address | The address of the standardized token deployer contract. | +| addr | address | the address to query for | -### tokenManagerAddress +## IERC20BurnableFrom + +_Interface of the ERC20 standard as defined in the EIP._ + +### burnFrom ```solidity -function tokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_) +function burnFrom(address from, uint256 amount) external ``` -Returns the address of the token manager associated with the given tokenId. +Function to burn tokens +Requires the caller to have allowance for `amount` on `from` + +_Can only be called by the distributor address._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the token manager. | +| from | address | The address that will have its tokens burnt | +| amount | uint256 | The amount of tokens to burn | -#### Return Values +## IERC20MintableBurnable -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenManagerAddress_ | address | The address of the token manager. | +_Interface of the ERC20 standard as defined in the EIP._ -### validTokenManagerAddress +### mint ```solidity -function validTokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_) +function mint(address to, uint256 amount) external ``` -Returns the address of the valid token manager associated with the given tokenId. - -#### Parameters +Function to mint new tokens -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the token manager. | +_Can only be called by the distributor address._ -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenManagerAddress_ | address | The address of the valid token manager. | +| to | address | The address that will receive the minted tokens | +| amount | uint256 | The amount of tokens to mint | -### tokenAddress +### burn ```solidity -function tokenAddress(bytes32 tokenId) external view returns (address tokenAddress_) +function burn(address from, uint256 amount) external ``` -Returns the address of the token associated with the given tokenId. +Function to burn tokens + +_Can only be called by the distributor address._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the token manager. | +| from | address | The address that will have its tokens burnt | +| amount | uint256 | The amount of tokens to burn | -#### Return Values +## IERC20Named -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenAddress_ | address | The address of the token. | +_Interface of the ERC20 standard as defined in the EIP._ -### interchainTokenAddress +### name ```solidity -function interchainTokenAddress(bytes32 tokenId) external view returns (address tokenAddress_) +function name() external view returns (string) ``` -Returns the address of the standardized token associated with the given tokenId. - -#### Parameters +Getter for the name of the token -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the standardized token. | +### symbol -#### Return Values +```solidity +function symbol() external view returns (string) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenAddress_ | address | The address of the standardized token. | +Getter for the symbol of the token -### interchainTokenId +### decimals ```solidity -function interchainTokenId(address operator_, bytes32 salt) external view returns (bytes32 tokenId) +function decimals() external view returns (uint8) ``` -Returns the custom tokenId associated with the given operator and salt. +Getter for the decimals of the token -#### Parameters +## IFlowLimit -| Name | Type | Description | -| ---- | ---- | ----------- | -| operator_ | address | The operator address. | -| salt | bytes32 | The salt used for token id calculation. | +### FlowLimitExceeded -#### Return Values +```solidity +error FlowLimitExceeded(uint256 limit, uint256 flowAmount) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | The custom tokenId associated with the operator and salt. | +### FlowLimitSet -### deployTokenManager +```solidity +event FlowLimitSet(bytes32 tokenId, address operator, uint256 flowLimit_) +``` + +### flowLimit ```solidity -function deployTokenManager(bytes32 salt, string destinationChain, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params, uint256 gasValue) external payable returns (bytes32 tokenId) +function flowLimit() external view returns (uint256 flowLimit_) ``` -Deploys a custom token manager contract on a remote chain. +Returns the current flow limit -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| salt | bytes32 | The salt used for token manager deployment. | -| destinationChain | string | The name of the destination chain. | -| tokenManagerType | enum ITokenManagerType.TokenManagerType | The type of token manager. | -| params | bytes | The deployment parameters. | -| gasValue | uint256 | The gas value for deployment. | +| flowLimit_ | uint256 | The current flow limit value | -### deployInterchainToken +### flowOutAmount ```solidity -function deployInterchainToken(bytes32 salt, string destinationChain, string name, string symbol, uint8 decimals, bytes distributor, bytes operator, uint256 gasValue) external payable +function flowOutAmount() external view returns (uint256 flowOutAmount_) ``` -Deploys and registers a standardized token on a remote chain. +Returns the current flow out amount -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| salt | bytes32 | The salt used for token deployment. | -| destinationChain | string | The name of the destination chain. Use '' for this chain. | -| name | string | The name of the standardized tokens. | -| symbol | string | The symbol of the standardized tokens. | -| decimals | uint8 | The number of decimals for the standardized tokens. | -| distributor | bytes | The distributor data for mint/burn operations. | -| operator | bytes | | -| gasValue | uint256 | The gas value for deployment. | +| flowOutAmount_ | uint256 | The current flow out amount | -### tokenManagerImplementation +### flowInAmount ```solidity -function tokenManagerImplementation(uint256 tokenManagerType) external view returns (address tokenManagerAddress_) +function flowInAmount() external view returns (uint256 flowInAmount_) ``` -Returns the implementation address for a given token manager type. - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenManagerType | uint256 | The type of token manager. | +Returns the current flow in amount #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenManagerAddress_ | address | The address of the token manager implementation. | - -### interchainTransfer +| flowInAmount_ | uint256 | The current flow in amount | -```solidity -function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable -``` +## IImplementation -### sendTokenWithData +### NotProxy ```solidity -function sendTokenWithData(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable +error NotProxy() ``` -### transmitSendToken +### setup ```solidity -function transmitSendToken(bytes32 tokenId, address sourceAddress, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable +function setup(bytes params) external ``` -Initiates an interchain token transfer. Only callable by TokenManagers +Called by the proxy to setup itself. + +_This should be hidden by the proxy._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the token to be transmitted. | -| sourceAddress | address | The source address of the token. | -| destinationChain | string | The name of the destination chain. | -| destinationAddress | bytes | The destination address on the destination chain. | -| amount | uint256 | The amount of tokens to transmit. | -| metadata | bytes | The metadata associated with the transmission. | +| params | bytes | the data to be used for the initialization. | -### setFlowLimits +## IInterchainToken + +_Interface of the ERC20 standard as defined in the EIP._ + +### tokenManager ```solidity -function setFlowLimits(bytes32[] tokenIds, uint256[] flowLimits) external +function tokenManager() external view returns (contract ITokenManager tokenManager_) ``` -Sets the flow limits for multiple tokens. +Getter for the tokenManager used for this token. -#### Parameters +_Needs to be overwitten._ + +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenIds | bytes32[] | An array of tokenIds. | -| flowLimits | uint256[] | An array of flow limits corresponding to the tokenIds. | +| tokenManager_ | contract ITokenManager | the TokenManager called to facilitate cross chain transfers. | -### flowLimit +### interchainTransfer ```solidity -function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_) +function interchainTransfer(string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable ``` -Returns the flow limit for a specific token. - -#### Parameters +Implementation of the interchainTransfer method -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the token. | +_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. +A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowLimit_ | uint256 | The flow limit for the token. | +| destinationChain | string | The destination chain identifier. | +| recipient | bytes | The bytes representation of the address of the recipient. | +| amount | uint256 | The amount of token to be transferred. | +| metadata | bytes | Either empty, to just facilitate an interchain transfer, or the data can be passed for an interchain contract call with transfer as per semantics defined by the token service. | -### flowOutAmount +### interchainTransferFrom ```solidity -function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_) +function interchainTransferFrom(address sender, string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable ``` -Returns the total amount of outgoing flow for a specific token. +Implementation of the interchainTransferFrom method + +_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. +A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the token. | +| sender | address | the sender of the tokens. They need to have approved `msg.sender` before this is called. | +| destinationChain | string | the string representation of the destination chain. | +| recipient | bytes | the bytes representation of the address of the recipient. | +| amount | uint256 | the amount of token to be transferred. | +| metadata | bytes | either empty, to just facilitate a cross-chain transfer, or the data to be passed to a cross-chain contract call and transfer. | -#### Return Values +## IInterchainTokenDeployer -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowOutAmount_ | uint256 | The total amount of outgoing flow for the token. | +This contract is used to deploy new instances of the StandardizedTokenProxy contract. -### flowInAmount +### AddressZero ```solidity -function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_) +error AddressZero() ``` -Returns the total amount of incoming flow for a specific token. +### TokenDeploymentFailed -#### Parameters +```solidity +error TokenDeploymentFailed() +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | The tokenId of the token. | +### implementationAddress -#### Return Values +```solidity +function implementationAddress() external view returns (address) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowInAmount_ | uint256 | The total amount of incoming flow for the token. | +Returns the standardized token implementation address -### setPaused +### deployedAddress ```solidity -function setPaused(bool paused) external +function deployedAddress(bytes32 salt) external view returns (address tokenAddress) ``` -Sets the paused state of the contract. +Returns the standardized token deployment address. -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| paused | bool | The boolean value indicating whether the contract is paused or not. | - -## IOperatable +| tokenAddress | address | the token address. | -### transferOperatorship +### deployInterchainToken ```solidity -function transferOperatorship(address operator_) external +function deployInterchainToken(bytes32 salt, address tokenManager, address distributor, string name, string symbol, uint8 decimals) external payable returns (address tokenAddress) ``` -Change the operator of the contract - -_Can only be called by the current operator_ +Deploys a new instance of the StandardizedTokenProxy contract #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| operator_ | address | The address of the new operator | +| salt | bytes32 | The salt used by Create3Deployer | +| tokenManager | address | Address of the token manager | +| distributor | address | Address of the distributor | +| name | string | Name of the token | +| symbol | string | Symbol of the token | +| decimals | uint8 | Decimals of the token | -### proposeOperatorship +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress | address | Address of the deployed token | + +## IInterchainTokenExecutable + +Implement this to accept calls from the InterchainTokenService. + +### executeWithInterchainToken ```solidity -function proposeOperatorship(address operator_) external +function executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external returns (bytes32) ``` -Proposed a change of the operator of the contract +This will be called after the tokens arrive to this contract -_Can only be called by the current operator_ +_Executable should revert unless the msg.sender is the InterchainTokenService_ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| operator_ | address | The address of the new operator | - -### acceptOperatorship - -```solidity -function acceptOperatorship(address fromOperator) external -``` +| sourceChain | string | the name of the source chain | +| sourceAddress | bytes | the address that sent the contract call | +| data | bytes | the data to be processed | +| tokenId | bytes32 | the tokenId of the token manager managing the token. | +| token | address | the address of the token. | +| amount | uint256 | the amount of token that was sent | -Accept a proposed change of operatorship +## IInterchainTokenExpressExecutable -_Can only be called by the proposed operator_ +Implement this to accept express calls from the InterchainTokenService. -### isOperator +### expressExecuteWithInterchainToken ```solidity -function isOperator(address addr) external view returns (bool) +function expressExecuteWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external returns (bytes32) ``` -Query if an address is a operator +This will be called after the tokens arrive to this contract + +_Executable should revert unless the msg.sender is the InterchainTokenService_ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| addr | address | the address to query for | +| sourceChain | string | the name of the source chain | +| sourceAddress | bytes | the address that sent the contract call | +| data | bytes | the data to be processed | +| tokenId | bytes32 | the token id of the token manager managing the token. | +| token | address | the address of the token. | +| amount | uint256 | the amount of token that was sent | -## IStandardizedToken +## IInterchainTokenService -This contract implements a standardized token which extends InterchainToken functionality. -This contract also inherits Distributable and Implementation logic. +### ZeroAddress -### TokenManagerAddressZero +```solidity +error ZeroAddress() +``` + +### LengthMismatch ```solidity -error TokenManagerAddressZero() +error LengthMismatch() ``` -### TokenNameEmpty +### InvalidTokenManagerImplementationType ```solidity -error TokenNameEmpty() +error InvalidTokenManagerImplementationType(address implementation) ``` -### setup +### NotRemoteService ```solidity -function setup(bytes params) external +error NotRemoteService() ``` -Called by the proxy to setup itself. +### TokenManagerDoesNotExist -_This should be hidden by the proxy._ +```solidity +error TokenManagerDoesNotExist(bytes32 tokenId) +``` -#### Parameters +### NotTokenManager -| Name | Type | Description | -| ---- | ---- | ----------- | -| params | bytes | the data to be used for the initialization. | +```solidity +error NotTokenManager(address caller, address tokenManager) +``` -### tokenManager +### ExecuteWithInterchainTokenFailed ```solidity -function tokenManager() external view returns (contract ITokenManager tokenManager_) +error ExecuteWithInterchainTokenFailed(address contractAddress) ``` -Getter for the tokenManager used for this token. +### ExpressExecuteWithInterchainTokenFailed -_Needs to be overwitten._ +```solidity +error ExpressExecuteWithInterchainTokenFailed(address contractAddress) +``` -#### Return Values +### GatewayToken -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenManager_ | contract ITokenManager | the TokenManager called to facilitate cross chain transfers. | +```solidity +error GatewayToken() +``` -## ITokenManager +### TokenManagerDeploymentFailed -This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. +```solidity +error TokenManagerDeploymentFailed(bytes error) +``` -### TokenLinkerZeroAddress +### InterchainTokenDeploymentFailed ```solidity -error TokenLinkerZeroAddress() +error InterchainTokenDeploymentFailed(bytes error) ``` -### NotService +### InvalidMessageType ```solidity -error NotService(address caller) +error InvalidMessageType(uint256 messageType) ``` -### TakeTokenFailed +### InvalidMetadataVersion ```solidity -error TakeTokenFailed() +error InvalidMetadataVersion(uint32 version) ``` -### GiveTokenFailed +### ExecuteWithTokenNotSupported ```solidity -error GiveTokenFailed() +error ExecuteWithTokenNotSupported() ``` -### NotToken +### UntrustedChain ```solidity -error NotToken(address caller) +error UntrustedChain(string chainName) ``` -### ZeroAddress +### InvalidExpressMessageType ```solidity -error ZeroAddress() +error InvalidExpressMessageType(uint256 messageType) ``` -### AlreadyFlowLimiter +### InterchainTransfer ```solidity -error AlreadyFlowLimiter(address flowLimiter) +event InterchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount) ``` -### NotFlowLimiter +### InterchainTransferWithData ```solidity -error NotFlowLimiter(address flowLimiter) +event InterchainTransferWithData(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, address sourceAddress, bytes data) ``` -### interchainTokenId +### InterchainTransferReceived ```solidity -function interchainTokenId() external view returns (bytes32) +event InterchainTransferReceived(bytes32 tokenId, string sourceChain, bytes sourceAddress, address destinationAddress, uint256 amount) ``` -A function that returns the token id. +### InterchainTransferReceivedWithData -### tokenAddress +```solidity +event InterchainTransferReceivedWithData(bytes32 tokenId, string sourceChain, bytes sourceAddress, address destinationAddress, uint256 amount) +``` + +### TokenManagerDeploymentStarted ```solidity -function tokenAddress() external view returns (address) +event TokenManagerDeploymentStarted(bytes32 tokenId, string destinationChain, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) ``` -A function that should return the address of the token. -Must be overridden in the inheriting contract. +### InterchainTokenDeploymentStarted -#### Return Values +```solidity +event InterchainTokenDeploymentStarted(bytes32 tokenId, string tokenName, string tokenSymbol, uint8 tokenDecimals, bytes distributor, bytes operator, string destinationChain) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | address | address address of the token. | +### TokenManagerDeployed -### implementationType +```solidity +event TokenManagerDeployed(bytes32 tokenId, address tokenManager, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params) +``` + +### InterchainTokenDeployed ```solidity -function implementationType() external pure returns (uint256) +event InterchainTokenDeployed(bytes32 tokenId, address tokenAddress, address distributor, string name, string symbol, uint8 decimals) ``` -A function that should return the implementation type of the token manager. +### InterchainTokenIdClaimed -### interchainTransfer +```solidity +event InterchainTokenIdClaimed(bytes32 tokenId, address deployer, bytes32 salt) +``` + +### interchainAddressTracker ```solidity -function interchainTransfer(string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable +function interchainAddressTracker() external view returns (contract IInterchainAddressTracker interchainAddressTracker_) ``` -Calls the service to initiate a cross-chain transfer after taking the appropriate amount of tokens from the user. +Returns the address of the interchain router contract. -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| destinationChain | string | the name of the chain to send tokens to. | -| destinationAddress | bytes | the address of the user to send tokens to. | -| amount | uint256 | the amount of tokens to take from msg.sender. | -| metadata | bytes | any additional data to be sent with the transfer. | +| interchainAddressTracker_ | contract IInterchainAddressTracker | The interchainAddressTracker. | -### callContractWithInterchainToken +### tokenManagerDeployer ```solidity -function callContractWithInterchainToken(string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable +function tokenManagerDeployer() external view returns (address tokenManagerDeployerAddress) ``` -Calls the service to initiate a cross-chain transfer with data after taking the appropriate amount of tokens from the user. +Returns the address of the token manager deployer contract. -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| destinationChain | string | the name of the chain to send tokens to. | -| destinationAddress | bytes | the address of the user to send tokens to. | -| amount | uint256 | the amount of tokens to take from msg.sender. | -| data | bytes | the data to pass to the destination contract. | +| tokenManagerDeployerAddress | address | The address of the token manager deployer contract. | -### transmitInterchainTransfer +### interchainTokenDeployer ```solidity -function transmitInterchainTransfer(address sender, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable +function interchainTokenDeployer() external view returns (address interchainTokenDeployerAddress) ``` -Calls the service to initiate a cross-chain transfer after taking the appropriate amount of tokens from the user. This can only be called by the token itself. +Returns the address of the standardized token deployer contract. -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| sender | address | the address of the user paying for the cross chain transfer. | -| destinationChain | string | the name of the chain to send tokens to. | -| destinationAddress | bytes | the address of the user to send tokens to. | -| amount | uint256 | the amount of tokens to take from msg.sender. | -| metadata | bytes | any additional data to be sent with the transfer. | +| interchainTokenDeployerAddress | address | The address of the standardized token deployer contract. | -### giveToken +### tokenManagerAddress ```solidity -function giveToken(address destinationAddress, uint256 amount) external returns (uint256) +function tokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_) ``` -This function gives token to a specified address. Can only be called by the service. +Returns the address of the token manager associated with the given tokenId. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| destinationAddress | address | the address to give tokens to. | -| amount | uint256 | the amount of token to give. | +| tokenId | bytes32 | The tokenId of the token manager. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | the amount of token actually given, which will only be different than `amount` in cases where the token takes some on-transfer fee. | +| tokenManagerAddress_ | address | The address of the token manager. | -### takeToken +### validTokenManagerAddress ```solidity -function takeToken(address sourceAddress, uint256 amount) external returns (uint256) +function validTokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_) ``` -This function takes token to from a specified address. Can only be called by the service. +Returns the address of the valid token manager associated with the given tokenId. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| sourceAddress | address | the address to take tokens from. | -| amount | uint256 | the amount of token to take. | +| tokenId | bytes32 | The tokenId of the token manager. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | the amount of token actually taken, which will onle be differen than `amount` in cases where the token takes some on-transfer fee. | +| tokenManagerAddress_ | address | The address of the valid token manager. | -### setFlowLimit +### tokenAddress ```solidity -function setFlowLimit(uint256 flowLimit_) external +function tokenAddress(bytes32 tokenId) external view returns (address tokenAddress_) ``` -This function sets the flow limit for this TokenManager. Can only be called by the operator. +Returns the address of the token associated with the given tokenId. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowLimit_ | uint256 | the maximum difference between the tokens flowing in and/or out at any given interval of time (6h) | - -## ITokenManagerDeployer - -This contract is used to deploy new instances of the TokenManagerProxy contract. - -### AddressZero - -```solidity -error AddressZero() -``` +| tokenId | bytes32 | The tokenId of the token manager. | -### TokenManagerDeploymentFailed +#### Return Values -```solidity -error TokenManagerDeploymentFailed() -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress_ | address | The address of the token. | -### deployTokenManager +### interchainTokenAddress ```solidity -function deployTokenManager(bytes32 tokenId, uint256 implementationType, bytes params) external payable returns (address tokenManager) +function interchainTokenAddress(bytes32 tokenId) external view returns (address tokenAddress_) ``` -Deploys a new instance of the TokenManagerProxy contract +Returns the address of the standardized token associated with the given tokenId. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenId | bytes32 | The unique identifier for the token | -| implementationType | uint256 | Token manager implementation type | -| params | bytes | Additional parameters used in the setup of the token manager | +| tokenId | bytes32 | The tokenId of the standardized token. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenManager | address | Address of the deployed tokenManager | - -## ITokenManagerLiquidityPool - -This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. +| tokenAddress_ | address | The address of the standardized token. | -### params +### interchainTokenId ```solidity -function params(bytes operator_, address tokenAddress_, address liquidityPool_) external pure returns (bytes params_) +function interchainTokenId(address operator_, bytes32 salt) external view returns (bytes32 tokenId) ``` -Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. +Returns the custom tokenId associated with the given operator and salt. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| operator_ | bytes | the operator of the TokenManager. | -| tokenAddress_ | address | the token to be managed. | -| liquidityPool_ | address | he address of the liquidity pool. | +| operator_ | address | The operator address. | +| salt | bytes32 | The salt used for token id calculation. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | +| tokenId | bytes32 | The custom tokenId associated with the operator and salt. | -### liquidityPool +### deployTokenManager ```solidity -function liquidityPool() external view returns (address liquidityPool_) +function deployTokenManager(bytes32 salt, string destinationChain, enum ITokenManagerType.TokenManagerType tokenManagerType, bytes params, uint256 gasValue) external payable returns (bytes32 tokenId) ``` -_Reads the stored liquidity pool address from the specified storage slot_ +Deploys a custom token manager contract on a remote chain. -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| liquidityPool_ | address | The address of the liquidity pool | +| salt | bytes32 | The salt used for token manager deployment. | +| destinationChain | string | The name of the destination chain. | +| tokenManagerType | enum ITokenManagerType.TokenManagerType | The type of token manager. | +| params | bytes | The deployment parameters. | +| gasValue | uint256 | The gas value for deployment. | -### setLiquidityPool +### deployInterchainToken ```solidity -function setLiquidityPool(address newLiquidityPool) external +function deployInterchainToken(bytes32 salt, string destinationChain, string name, string symbol, uint8 decimals, bytes distributor, bytes operator, uint256 gasValue) external payable ``` -_Updates the address of the liquidity pool. Can only be called by the operator._ +Deploys and registers a standardized token on a remote chain. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| newLiquidityPool | address | The new address of the liquidity pool | - -## ITokenManagerLockUnlock - -This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. +| salt | bytes32 | The salt used for token deployment. | +| destinationChain | string | The name of the destination chain. Use '' for this chain. | +| name | string | The name of the standardized tokens. | +| symbol | string | The symbol of the standardized tokens. | +| decimals | uint8 | The number of decimals for the standardized tokens. | +| distributor | bytes | The distributor data for mint/burn operations. | +| operator | bytes | | +| gasValue | uint256 | The gas value for deployment. | -### params +### tokenManagerImplementation ```solidity -function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) +function tokenManagerImplementation(uint256 tokenManagerType) external view returns (address tokenManagerAddress_) ``` -Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. +Returns the implementation address for a given token manager type. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| operator_ | bytes | the operator of the TokenManager. | -| tokenAddress_ | address | the token to be managed. | +| tokenManagerType | uint256 | The type of token manager. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | +| tokenManagerAddress_ | address | The address of the token manager implementation. | -## ITokenManagerMintBurn +### interchainTransfer -This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. +```solidity +function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable +``` -### params +### callContractWithInterchainToken ```solidity -function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) +function callContractWithInterchainToken(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable ``` -Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. +### transmitInterchainTransfer -#### Parameters +```solidity +function transmitInterchainTransfer(bytes32 tokenId, address sourceAddress, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| operator_ | bytes | the operator of the TokenManager. | -| tokenAddress_ | address | the token to be managed. | +Initiates an interchain token transfer. Only callable by TokenManagers -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | - -## ITokenManagerProxy - -_This contract is a proxy for token manager contracts. It implements ITokenManagerProxy and -inherits from FixedProxy from the gmp sdk repo_ +| tokenId | bytes32 | The tokenId of the token to be transmitted. | +| sourceAddress | address | The source address of the token. | +| destinationChain | string | The name of the destination chain. | +| destinationAddress | bytes | The destination address on the destination chain. | +| amount | uint256 | The amount of tokens to transmit. | +| metadata | bytes | The metadata associated with the transmission. | -### ImplementationLookupFailed +### setFlowLimits ```solidity -error ImplementationLookupFailed() +function setFlowLimits(bytes32[] tokenIds, uint256[] flowLimits) external ``` -### SetupFailed - -```solidity -error SetupFailed(bytes returnData) -``` +Sets the flow limits for multiple tokens. -### NativeTokenNotAccepted +#### Parameters -```solidity -error NativeTokenNotAccepted() -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenIds | bytes32[] | An array of tokenIds. | +| flowLimits | uint256[] | An array of flow limits corresponding to the tokenIds. | -### implementationType +### flowLimit ```solidity -function implementationType() external view returns (uint256) +function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_) ``` -Returns implementation type of this token manager - -### implementation +Returns the flow limit for a specific token. -```solidity -function implementation() external view returns (address) -``` +#### Parameters -Returns the address of the current implementation. +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | The tokenId of the token. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | address | impl The address of the current implementation | +| flowLimit_ | uint256 | The flow limit for the token. | -### interchainTokenId +### flowOutAmount ```solidity -function interchainTokenId() external view returns (bytes32) +function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_) ``` -Returns token ID of the token manager. - -## ITokenManagerType +Returns the total amount of outgoing flow for a specific token. -A simple interface that defines all the token manager types +#### Parameters -### TokenManagerType +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | The tokenId of the token. | -```solidity -enum TokenManagerType { - MINT_BURN, - MINT_BURN_FROM, - LOCK_UNLOCK, - LOCK_UNLOCK_FEE -} -``` +#### Return Values -## ITokenRegistrar +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowOutAmount_ | uint256 | The total amount of outgoing flow for the token. | -### ZeroAddress +### flowInAmount ```solidity -error ZeroAddress() +function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_) ``` -### NotDistributor - -```solidity -error NotDistributor(address distributor) -``` +Returns the total amount of incoming flow for a specific token. -### NotOperator +#### Parameters -```solidity -error NotOperator(address operator) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | The tokenId of the token. | -### NonZeroMintAmount +#### Return Values -```solidity -error NonZeroMintAmount() -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowInAmount_ | uint256 | The total amount of incoming flow for the token. | -### ApproveFailed +### setPauseStatus ```solidity -error ApproveFailed() +function setPauseStatus(bool paused) external ``` -### chainNameHash +Allows the owner to pause/unpause the token service. -```solidity -function chainNameHash() external view returns (bytes32) -``` +#### Parameters -### standardizedTokenSalt +| Name | Type | Description | +| ---- | ---- | ----------- | +| paused | bool | whether to pause or unpause. | -```solidity -function standardizedTokenSalt(bytes32 chainAddressHash_, address deployer, bytes32 salt) external view returns (bytes32) -``` +## IOperatable -### standardizedTokenId +### transferOperatorship ```solidity -function standardizedTokenId(address deployer, bytes32 salt) external view returns (bytes32 tokenId) +function transferOperatorship(address operator_) external ``` -### interchainTokenAddress +Change the operator of the contract -```solidity -function interchainTokenAddress(address deployer, bytes32 salt) external view returns (address tokenAddress) -``` +_Can only be called by the current operator_ -### deployInterchainToken +#### Parameters -```solidity -function deployInterchainToken(bytes32 salt, string name, string symbol, uint8 decimals, uint256 mintAmount, address distributor, address operator) external payable -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | address | The address of the new operator | -### deployRemoteInterchainToken +### proposeOperatorship ```solidity -function deployRemoteInterchainToken(string originalChainName, bytes32 salt, address additionalDistributor, address optionalOperator, string destinationChain, uint256 gasValue) external payable +function proposeOperatorship(address operator_) external ``` -### canonicalTokenSalt +Proposed a change of the operator of the contract -```solidity -function canonicalTokenSalt(bytes32 chainAddressHash_, address tokenAddress) external view returns (bytes32 salt) -``` +_Can only be called by the current operator_ -### canonicalTokenId +#### Parameters -```solidity -function canonicalTokenId(address tokenAddress) external view returns (bytes32 tokenId) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | address | The address of the new operator | -### registerCanonicalToken +### acceptOperatorship ```solidity -function registerCanonicalToken(address tokenAddress) external payable returns (bytes32 tokenId) +function acceptOperatorship(address fromOperator) external ``` -### deployRemoteCanonicalToken +Accept a proposed change of operatorship -```solidity -function deployRemoteCanonicalToken(string originalChainName, address originalAddress, string destinationChain, uint256 gasValue) external payable -``` +_Can only be called by the proposed operator_ -### interchainTransfer +### isOperator ```solidity -function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable +function isOperator(address addr) external view returns (bool) ``` -### interchainTransferFrom +Query if an address is a operator -```solidity -function interchainTransferFrom(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable -``` +#### Parameters -## TokenManagerProxy +| Name | Type | Description | +| ---- | ---- | ----------- | +| addr | address | the address to query for | -This contract is a proxy for token manager contracts. +## IStandardizedToken -_It implements ITokenManagerProxy._ +This contract implements a standardized token which extends InterchainToken functionality. +This contract also inherits Distributable and Implementation logic. -### interchainTokenService +### TokenManagerAddressZero ```solidity -contract IInterchainTokenService interchainTokenService +error TokenManagerAddressZero() ``` -### implementationType +### TokenNameEmpty ```solidity -uint256 implementationType +error TokenNameEmpty() ``` -Returns implementation type of this token manager - -### interchainTokenId +### setup ```solidity -bytes32 interchainTokenId +function setup(bytes params) external ``` -Returns token ID of the token manager. - -### constructor - -```solidity -constructor(address interchainTokenServiceAddress_, uint256 implementationType_, bytes32 tokenId, bytes params) public -``` +Called by the proxy to setup itself. -_Constructs the TokenManagerProxy contract._ +_This should be hidden by the proxy._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| interchainTokenServiceAddress_ | address | The address of the interchain token service | -| implementationType_ | uint256 | The token manager type | -| tokenId | bytes32 | The identifier for the token | -| params | bytes | The initialization parameters for the token manager contract | +| params | bytes | the data to be used for the initialization. | -### implementation - -```solidity -function implementation() public view returns (address impl) -``` - -_Returns the address of the current implementation._ - -#### Return Values - -| Name | Type | Description | -| ---- | ---- | ----------- | -| impl | address | The address of the current implementation | - -### _tokenManagerImplementation +### tokenManager ```solidity -function _tokenManagerImplementation(contract IInterchainTokenService interchainTokenServiceAddress_, uint256 implementationType_) internal view returns (address impl) +function tokenManager() external view returns (contract ITokenManager tokenManager_) ``` -_Returns the implementation address from the interchain token service for the provided type._ - -#### Parameters +Getter for the tokenManager used for this token. -| Name | Type | Description | -| ---- | ---- | ----------- | -| interchainTokenServiceAddress_ | contract IInterchainTokenService | The address of the interchain token service | -| implementationType_ | uint256 | The token manager type | +_Needs to be overwitten._ #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| impl | address | The address of the implementation | - -### setup - -```solidity -function setup(bytes setupParams) external -``` - -_Setup function. Empty in this contract._ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| setupParams | bytes | Initialization parameters | - -### receive - -```solidity -receive() external payable virtual -``` - -_Reverts if native token is sent._ - -### fallback - -```solidity -fallback() external payable virtual -``` - -_Fallback function. Delegates the call to the token manager contract._ - -## Invalid - -```solidity -error Invalid() -``` - -## TestTokenManager - -### NAME - -```solidity -string NAME -``` - -### constructor - -```solidity -constructor(address interchainTokenService_) public -``` - -## TestDistributable - -### NAME - -```solidity -string NAME -``` - -### constructor +| tokenManager_ | contract ITokenManager | the TokenManager called to facilitate cross chain transfers. | -```solidity -constructor() public -``` +## ITokenManager -## TestFlowLimit +This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. -### NAME +### TokenLinkerZeroAddress ```solidity -string NAME +error TokenLinkerZeroAddress() ``` -### constructor +### NotService ```solidity -constructor() public +error NotService(address caller) ``` -## TestOperatable - -### NAME +### TakeTokenFailed ```solidity -string NAME +error TakeTokenFailed() ``` -### constructor +### GiveTokenFailed ```solidity -constructor() public +error GiveTokenFailed() ``` -## TokenManager - -This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. - -### interchainTokenService +### NotToken ```solidity -contract IInterchainTokenService interchainTokenService +error NotToken(address caller) ``` -### TOKEN_ADDRESS_SLOT +### ZeroAddress ```solidity -uint256 TOKEN_ADDRESS_SLOT +error ZeroAddress() ``` -### constructor +### AlreadyFlowLimiter ```solidity -constructor(address interchainTokenService_) internal +error AlreadyFlowLimiter(address flowLimiter) ``` -Constructs the TokenManager contract. - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| interchainTokenService_ | address | The address of the interchain token service | - -### onlyService +### NotFlowLimiter ```solidity -modifier onlyService() +error NotFlowLimiter(address flowLimiter) ``` -_A modifier that allows only the interchain token service to execute the function._ - -### onlyToken +### interchainTokenId ```solidity -modifier onlyToken() +function interchainTokenId() external view returns (bytes32) ``` -_A modifier that allows only the token to execute the function._ +A function that returns the token id. ### tokenAddress ```solidity -function tokenAddress() public view virtual returns (address tokenAddress_) +function tokenAddress() external view returns (address) ``` -_Reads the stored token address from the predetermined storage slot_ +A function that should return the address of the token. +Must be overridden in the inheriting contract. #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenAddress_ | address | The address of the token | - -### interchainTokenId - -```solidity -function interchainTokenId() public view returns (bytes32) -``` - -A function that returns the token id. - -_This will only work when implementation is called by a proxy, which stores the tokenId as an immutable._ +| [0] | address | address address of the token. | -### setup +### implementationType ```solidity -function setup(bytes params) external +function implementationType() external pure returns (uint256) ``` -_This function should only be called by the proxy, and only once from the proxy constructor_ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| params | bytes | the parameters to be used to initialize the TokenManager. The exact format depends on the type of TokenManager used but the first 32 bytes are reserved for the address of the operator, stored as bytes (to be compatible with non-EVM chains) | +A function that should return the implementation type of the token manager. ### interchainTransfer ```solidity -function interchainTransfer(string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable virtual +function interchainTransfer(string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable ``` Calls the service to initiate a cross-chain transfer after taking the appropriate amount of tokens from the user. @@ -2521,7 +2282,7 @@ Calls the service to initiate a cross-chain transfer after taking the appropriat ### callContractWithInterchainToken ```solidity -function callContractWithInterchainToken(string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable virtual +function callContractWithInterchainToken(string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable ``` Calls the service to initiate a cross-chain transfer with data after taking the appropriate amount of tokens from the user. @@ -2538,7 +2299,7 @@ Calls the service to initiate a cross-chain transfer with data after taking the ### transmitInterchainTransfer ```solidity -function transmitInterchainTransfer(address sender, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable virtual +function transmitInterchainTransfer(address sender, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable ``` Calls the service to initiate a cross-chain transfer after taking the appropriate amount of tokens from the user. This can only be called by the token itself. @@ -2551,7 +2312,7 @@ Calls the service to initiate a cross-chain transfer after taking the appropriat | destinationChain | string | the name of the chain to send tokens to. | | destinationAddress | bytes | the address of the user to send tokens to. | | amount | uint256 | the amount of tokens to take from msg.sender. | -| metadata | bytes | any additional data to be sent with the transfer | +| metadata | bytes | any additional data to be sent with the transfer. | ### giveToken @@ -2580,211 +2341,103 @@ This function gives token to a specified address. Can only be called by the serv function takeToken(address sourceAddress, uint256 amount) external returns (uint256) ``` -This function gives token to a specified address. Can only be called by the service. +This function takes token to from a specified address. Can only be called by the service. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| sourceAddress | address | the address to give tokens to. | -| amount | uint256 | the amount of token to give. | +| sourceAddress | address | the address to take tokens from. | +| amount | uint256 | the amount of token to take. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | the amount of token actually given, which will onle be differen than `amount` in cases where the token takes some on-transfer fee. | +| [0] | uint256 | the amount of token actually taken, which will onle be differen than `amount` in cases where the token takes some on-transfer fee. | -### addFlowLimiter +### setFlowLimit ```solidity -function addFlowLimiter(address flowLimiter) external +function setFlowLimit(uint256 flowLimit_) external ``` -This function adds a flow limiter for this TokenManager. Can only be called by the operator. +This function sets the flow limit for this TokenManager. Can only be called by the operator. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowLimiter | address | the address of the new flow limiter. | +| flowLimit_ | uint256 | the maximum difference between the tokens flowing in and/or out at any given interval of time (6h) | -### removeFlowLimiter +## ITokenManagerDeployer + +This contract is used to deploy new instances of the TokenManagerProxy contract. + +### AddressZero ```solidity -function removeFlowLimiter(address flowLimiter) external +error AddressZero() ``` -This function adds a flow limiter for this TokenManager. Can only be called by the operator. - -#### Parameters +### TokenManagerDeploymentFailed -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowLimiter | address | the address of the new flow limiter. | +```solidity +error TokenManagerDeploymentFailed() +``` -### setFlowLimit +### deployTokenManager ```solidity -function setFlowLimit(uint256 flowLimit_) external +function deployTokenManager(bytes32 tokenId, uint256 implementationType, bytes params) external payable returns (address tokenManager) ``` -This function sets the flow limit for this TokenManager. Can only be called by the flow limiters. +Deploys a new instance of the TokenManagerProxy contract #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowLimit_ | uint256 | the maximum difference between the tokens flowing in and/or out at any given interval of time (6h) | - -### _setTokenAddress - -```solidity -function _setTokenAddress(address tokenAddress_) internal -``` - -_Stores the token address in the predetermined storage slot_ +| tokenId | bytes32 | The unique identifier for the token | +| implementationType | uint256 | Token manager implementation type | +| params | bytes | Additional parameters used in the setup of the token manager | -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenAddress_ | address | The address of the token to store | +| tokenManager | address | Address of the deployed tokenManager | -### _takeToken +## ITokenManagerLiquidityPool + +This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. + +### params ```solidity -function _takeToken(address from, uint256 amount) internal virtual returns (uint256) +function params(bytes operator_, address tokenAddress_, address liquidityPool_) external pure returns (bytes params_) ``` -Transfers tokens from a specific address to this contract. -Must be overridden in the inheriting contract. +Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| from | address | The address from which the tokens will be sent | -| amount | uint256 | The amount of tokens to receive | - -#### Return Values - -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | uint256 | uint amount of tokens received | - -### _giveToken - -```solidity -function _giveToken(address receiver, uint256 amount) internal virtual returns (uint256) -``` - -Transfers tokens from this contract to a specific address. -Must be overridden in the inheriting contract. - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| receiver | address | The address to which the tokens will be sent | -| amount | uint256 | The amount of tokens to send | +| operator_ | bytes | the operator of the TokenManager. | +| tokenAddress_ | address | the token to be managed. | +| liquidityPool_ | address | he address of the liquidity pool. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | uint amount of tokens sent | - -### _setup - -```solidity -function _setup(bytes params) internal virtual -``` - -_Additional setup logic to perform -Must be overridden in the inheriting contract._ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| params | bytes | The setup parameters | - -## TokenManagerLiquidityPool - -This contract is a an implementation of TokenManager that stores all tokens in a separate liquity pool -rather than within itself. - -_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. -It uses the Axelar SDK to safely transfer tokens._ - -### NotSupported - -```solidity -error NotSupported() -``` - -### LIQUIDITY_POOL_SLOT - -```solidity -uint256 LIQUIDITY_POOL_SLOT -``` - -### constructor - -```solidity -constructor(address interchainTokenService_) public -``` - -_Constructs an instance of TokenManagerLiquidityPool. Calls the constructor -of TokenManagerAddressStorage which calls the constructor of TokenManager._ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| interchainTokenService_ | address | The address of the interchain token service contract | - -### implementationType - -```solidity -function implementationType() external pure returns (uint256) -``` - -A function that should return the implementation type of the token manager. - -### _setup - -```solidity -function _setup(bytes params_) internal -``` - -_Sets up the token address and liquidity pool address._ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address and the liquidity pool address. | - -### _setLiquidityPool - -```solidity -function _setLiquidityPool(address liquidityPool_) internal -``` - -_Stores the liquidity pool address at a specific storage slot_ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| liquidityPool_ | address | The address of the liquidity pool | +| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | ### liquidityPool ```solidity -function liquidityPool() public view returns (address liquidityPool_) +function liquidityPool() external view returns (address liquidityPool_) ``` _Reads the stored liquidity pool address from the specified storage slot_ @@ -2809,55 +2462,67 @@ _Updates the address of the liquidity pool. Can only be called by the operator._ | ---- | ---- | ----------- | | newLiquidityPool | address | The new address of the liquidity pool | -### _takeToken +## ITokenManagerLockUnlock + +This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. + +### params ```solidity -function _takeToken(address from, uint256 amount) internal returns (uint256) +function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) ``` -_Transfers a specified amount of tokens from a specified address to the liquidity pool._ +Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| from | address | The address to transfer tokens from | -| amount | uint256 | The amount of tokens to transfer | +| operator_ | bytes | the operator of the TokenManager. | +| tokenAddress_ | address | the token to be managed. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | uint The actual amount of tokens transferred. This allows support for fee-on-transfer tokens. | +| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | -### _giveToken +## ITokenManagerLockUnlockFee + +This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. + +### params ```solidity -function _giveToken(address to, uint256 amount) internal returns (uint256) +function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) ``` -_Transfers a specified amount of tokens from the liquidity pool to a specified address._ +Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| to | address | The address to transfer tokens to | -| amount | uint256 | The amount of tokens to transfer | +| operator_ | bytes | the operator of the TokenManager. | +| tokenAddress_ | address | the token to be managed. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | uint The actual amount of tokens transferred | +| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | + +## ITokenManagerMintBurn + +This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. ### params ```solidity -function params(bytes operator_, address tokenAddress_, address liquidityPoolAddress) external pure returns (bytes params_) +function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) ``` -Getter function for the parameters of a liquidity pool TokenManager. Mainly to be used by frontends. +Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. #### Parameters @@ -2865,7 +2530,6 @@ Getter function for the parameters of a liquidity pool TokenManager. Mainly to b | ---- | ---- | ----------- | | operator_ | bytes | the operator of the TokenManager. | | tokenAddress_ | address | the token to be managed. | -| liquidityPoolAddress | address | the liquidity pool to be used to store the bridged tokens. | #### Return Values @@ -2873,1201 +2537,1345 @@ Getter function for the parameters of a liquidity pool TokenManager. Mainly to b | ---- | ---- | ----------- | | params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | -## TokenManagerLockUnlock - -This contract is an implementation of TokenManager that locks and unlocks a specific token on behalf of the interchain token service. +## ITokenManagerProxy -_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. -It uses the Axelar SDK to safely transfer tokens._ +_This contract is a proxy for token manager contracts. It implements ITokenManagerProxy and +inherits from FixedProxy from the gmp sdk repo_ -### constructor +### ImplementationLookupFailed ```solidity -constructor(address interchainTokenService_) public +error ImplementationLookupFailed() ``` -_Constructs an instance of TokenManagerLockUnlock. Calls the constructor -of TokenManagerAddressStorage which calls the constructor of TokenManager._ +### SetupFailed -#### Parameters +```solidity +error SetupFailed(bytes returnData) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| interchainTokenService_ | address | The address of the interchain token service contract | +### NativeTokenNotAccepted + +```solidity +error NativeTokenNotAccepted() +``` ### implementationType ```solidity -function implementationType() external pure returns (uint256) +function implementationType() external view returns (uint256) ``` -A function that should return the implementation type of the token manager. +Returns implementation type of this token manager -### _setup +### implementation ```solidity -function _setup(bytes params_) internal +function implementation() external view returns (address) ``` -_Sets up the token address._ +Returns the address of the current implementation. -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address. | +| [0] | address | impl The address of the current implementation | -### _takeToken +### interchainTokenId ```solidity -function _takeToken(address from, uint256 amount) internal returns (uint256) +function interchainTokenId() external view returns (bytes32) ``` -_Transfers a specified amount of tokens from a specified address to this contract._ +Returns token ID of the token manager. -#### Parameters +## ITokenManagerType -| Name | Type | Description | -| ---- | ---- | ----------- | -| from | address | The address to transfer tokens from | -| amount | uint256 | The amount of tokens to transfer | +A simple interface that defines all the token manager types -#### Return Values +### TokenManagerType -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | uint256 | uint The actual amount of tokens transferred. This allows support for fee-on-transfer tokens. | +```solidity +enum TokenManagerType { + MINT_BURN, + MINT_BURN_FROM, + LOCK_UNLOCK, + LOCK_UNLOCK_FEE +} +``` -### _giveToken +## ITokenRegistrar + +### ZeroAddress ```solidity -function _giveToken(address to, uint256 amount) internal returns (uint256) +error ZeroAddress() ``` -_Transfers a specified amount of tokens from this contract to a specified address._ - -#### Parameters +### NotDistributor -| Name | Type | Description | -| ---- | ---- | ----------- | -| to | address | The address to transfer tokens to | -| amount | uint256 | The amount of tokens to transfer | +```solidity +error NotDistributor(address distributor) +``` -#### Return Values +### NotOperator -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | uint256 | uint The actual amount of tokens transferred | +```solidity +error NotOperator(address operator) +``` -### params +### NonZeroMintAmount ```solidity -function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) +error NonZeroMintAmount() ``` -Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. +### ApproveFailed -#### Parameters +```solidity +error ApproveFailed() +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| operator_ | bytes | the operator of the TokenManager. | -| tokenAddress_ | address | the token to be managed. | +### chainNameHash -#### Return Values +```solidity +function chainNameHash() external view returns (bytes32) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | +### standardizedTokenSalt -## TokenManagerLockUnlockFee +```solidity +function standardizedTokenSalt(bytes32 chainAddressHash_, address deployer, bytes32 salt) external view returns (bytes32) +``` -This contract is an implementation of TokenManager that locks and unlocks a specific token on behalf of the interchain token service. +### standardizedTokenId -_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. -It uses the Axelar SDK to safely transfer tokens._ +```solidity +function standardizedTokenId(address deployer, bytes32 salt) external view returns (bytes32 tokenId) +``` -### constructor +### interchainTokenAddress ```solidity -constructor(address interchainTokenService_) public +function interchainTokenAddress(address deployer, bytes32 salt) external view returns (address tokenAddress) ``` -_Constructs an instance of TokenManagerLockUnlock. Calls the constructor -of TokenManagerAddressStorage which calls the constructor of TokenManager._ - -#### Parameters +### deployInterchainToken -| Name | Type | Description | -| ---- | ---- | ----------- | -| interchainTokenService_ | address | The address of the interchain token service contract | +```solidity +function deployInterchainToken(bytes32 salt, string name, string symbol, uint8 decimals, uint256 mintAmount, address distributor, address operator) external payable +``` -### implementationType +### deployRemoteInterchainToken ```solidity -function implementationType() external pure returns (uint256) +function deployRemoteInterchainToken(string originalChainName, bytes32 salt, address additionalDistributor, address optionalOperator, string destinationChain, uint256 gasValue) external payable ``` -A function that should return the implementation type of the token manager. - -### _setup +### canonicalTokenSalt ```solidity -function _setup(bytes params_) internal +function canonicalTokenSalt(bytes32 chainAddressHash_, address tokenAddress) external view returns (bytes32 salt) ``` -_Sets up the token address._ +### canonicalTokenId -#### Parameters +```solidity +function canonicalTokenId(address tokenAddress) external view returns (bytes32 tokenId) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address. | +### registerCanonicalToken -### _takeToken +```solidity +function registerCanonicalToken(address tokenAddress) external payable returns (bytes32 tokenId) +``` + +### deployRemoteCanonicalToken ```solidity -function _takeToken(address from, uint256 amount) internal returns (uint256) +function deployRemoteCanonicalToken(string originalChainName, address originalAddress, string destinationChain, uint256 gasValue) external payable ``` -_Transfers a specified amount of tokens from a specified address to this contract._ +### interchainTransfer -#### Parameters +```solidity +function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| from | address | The address to transfer tokens from | -| amount | uint256 | The amount of tokens to transfer | +### interchainTransferFrom -#### Return Values +```solidity +function interchainTransferFrom(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | uint256 | uint The actual amount of tokens transferred. This allows support for fee-on-transfer tokens. | +## CanonicalTokenRegistrarProxy -### _giveToken +_Proxy contract for interchain token service contracts. Inherits from the Proxy contract._ + +### constructor ```solidity -function _giveToken(address to, uint256 amount) internal returns (uint256) +constructor(address implementationAddress, address owner) public ``` -_Transfers a specified amount of tokens from this contract to a specified address._ +_Constructs the InterchainTokenServiceProxy contract._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| to | address | The address to transfer tokens to | -| amount | uint256 | The amount of tokens to transfer | +| implementationAddress | address | Address of the interchain token service implementation | +| owner | address | Address of the owner of the proxy | + +### contractId + +```solidity +function contractId() internal pure returns (bytes32) +``` + +_Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract._ #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | uint The actual amount of tokens transferred | +| [0] | bytes32 | bytes32 identifier for this contract | -### params +## InterchainTokenServiceProxy + +_Proxy contract for interchain token service contracts. Inherits from the FinalProxy contract._ + +### constructor ```solidity -function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) +constructor(address implementationAddress, address owner, address operator) public ``` -Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. +_Constructs the InterchainTokenServiceProxy contract._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| operator_ | bytes | the operator of the TokenManager. | -| tokenAddress_ | address | the token to be managed. | +| implementationAddress | address | Address of the interchain token service implementation | +| owner | address | Address of the owner of the proxy | +| operator | address | | + +### contractId + +```solidity +function contractId() internal pure returns (bytes32) +``` + +_Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract._ #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | - -## TokenManagerMintBurn +| [0] | bytes32 | bytes32 identifier for this contract | -This contract is an implementation of TokenManager that mints and burns a specific token on behalf of the interchain token service. +## StandardizedTokenProxy -_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. -It uses the Axelar SDK to safely transfer tokens._ +_Proxy contract for StandardizedToken contracts. Inherits from FixedProxy._ ### constructor ```solidity -constructor(address interchainTokenService_) public +constructor(address implementationAddress, bytes params) public ``` -_Constructs an instance of TokenManagerMintBurn. Calls the constructor -of TokenManagerAddressStorage which calls the constructor of TokenManager._ +_Constructs the StandardizedTokenProxy contract._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| interchainTokenService_ | address | The address of the interchain token service contract | +| implementationAddress | address | Address of the StandardizedToken implementation | +| params | bytes | Initialization parameters for the StandardizedToken contract | -### implementationType +### contractId ```solidity -function implementationType() external pure virtual returns (uint256) +function contractId() internal pure returns (bytes32) ``` -A function that should return the implementation type of the token manager. +Getter for the contract id. -### _setup +## TokenManagerProxy -```solidity -function _setup(bytes params_) internal -``` +This contract is a proxy for token manager contracts. -_Sets up the token address._ +_It implements ITokenManagerProxy._ -#### Parameters +### interchainTokenService -| Name | Type | Description | -| ---- | ---- | ----------- | -| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address. | +```solidity +contract IInterchainTokenService interchainTokenService +``` -### _takeToken +### implementationType ```solidity -function _takeToken(address from, uint256 amount) internal virtual returns (uint256) +uint256 implementationType ``` -_Burns the specified amount of tokens from a particular address._ - -#### Parameters +Returns implementation type of this token manager -| Name | Type | Description | -| ---- | ---- | ----------- | -| from | address | Address to burn tokens from | -| amount | uint256 | Amount of tokens to burn | +### interchainTokenId -#### Return Values +```solidity +bytes32 interchainTokenId +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | uint256 | uint Amount of tokens burned | +Returns token ID of the token manager. -### _giveToken +### constructor ```solidity -function _giveToken(address to, uint256 amount) internal returns (uint256) +constructor(address interchainTokenServiceAddress_, uint256 implementationType_, bytes32 tokenId, bytes params) public ``` -_Mints the specified amount of tokens to a particular address_ +_Constructs the TokenManagerProxy contract._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| to | address | Address to mint tokens to | -| amount | uint256 | Amount of tokens to mint | +| interchainTokenServiceAddress_ | address | The address of the interchain token service | +| implementationType_ | uint256 | The token manager type | +| tokenId | bytes32 | The identifier for the token | +| params | bytes | The initialization parameters for the token manager contract | + +### implementation + +```solidity +function implementation() public view returns (address impl) +``` + +_Returns the address of the current implementation._ #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | uint Amount of tokens minted | +| impl | address | The address of the current implementation | -### params +### _tokenManagerImplementation ```solidity -function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) +function _tokenManagerImplementation(contract IInterchainTokenService interchainTokenServiceAddress_, uint256 implementationType_) internal view returns (address impl) ``` -Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. +_Returns the implementation address from the interchain token service for the provided type._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| operator_ | bytes | the operator of the TokenManager. | -| tokenAddress_ | address | the token to be managed. | +| interchainTokenServiceAddress_ | contract IInterchainTokenService | The address of the interchain token service | +| implementationType_ | uint256 | The token manager type | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | - -## TokenManagerMintBurnFrom - -This contract is an implementation of TokenManager that mints and burns a specific token on behalf of the interchain token service. - -_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. -It uses the Axelar SDK to safely transfer tokens._ +| impl | address | The address of the implementation | -### constructor +### setup ```solidity -constructor(address interchainTokenService_) public +function setup(bytes setupParams) external ``` -_Constructs an instance of TokenManagerMintBurn. Calls the constructor -of TokenManagerAddressStorage which calls the constructor of TokenManager._ +_Setup function. Empty in this contract._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| interchainTokenService_ | address | The address of the interchain token service contract | +| setupParams | bytes | Initialization parameters | -### implementationType +### receive ```solidity -function implementationType() external pure returns (uint256) +receive() external payable virtual ``` -A function that should return the implementation type of the token manager. +_Reverts if native token is sent._ -### _takeToken +### fallback ```solidity -function _takeToken(address from, uint256 amount) internal returns (uint256) +fallback() external payable virtual ``` -_Burns the specified amount of tokens from a particular address._ +_Fallback function. Delegates the call to the token manager contract._ -#### Parameters +## TokenRegistrarProxy -| Name | Type | Description | +_Proxy contract for interchain token service contracts. Inherits from the Proxy contract._ + +### constructor + +```solidity +constructor(address implementationAddress, address owner) public +``` + +_Constructs the InterchainTokenServiceProxy contract._ + +#### Parameters + +| Name | Type | Description | | ---- | ---- | ----------- | -| from | address | Address to burn tokens from | -| amount | uint256 | Amount of tokens to burn | +| implementationAddress | address | Address of the interchain token service implementation | +| owner | address | Address of the owner of the proxy | + +### contractId + +```solidity +function contractId() internal pure returns (bytes32) +``` + +_Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract._ #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | uint256 | uint Amount of tokens burned | +| [0] | bytes32 | bytes32 identifier for this contract | -## TokenRegistrar +## FeeOnTransferTokenTest -### NotApproved +### tokenManager_ ```solidity -error NotApproved(address tokenAddress) +contract ITokenManager tokenManager_ ``` -### service +### tokenManagerRequiresApproval_ ```solidity -contract IInterchainTokenService service +bool tokenManagerRequiresApproval_ ``` -### chainNameHash +### name ```solidity -bytes32 chainNameHash +string name ``` -### PREFIX_CANONICAL_TOKEN_SALT +### symbol ```solidity -bytes32 PREFIX_CANONICAL_TOKEN_SALT +string symbol ``` -### PREFIX_STANDARDIZED_TOKEN_SALT +### decimals ```solidity -bytes32 PREFIX_STANDARDIZED_TOKEN_SALT +uint8 decimals ``` ### constructor ```solidity -constructor(address interchainTokenServiceAddress) public +constructor(string name_, string symbol_, uint8 decimals_, address tokenManagerAddress) public ``` -### contractId +### tokenManager ```solidity -function contractId() external pure returns (bytes32) +function tokenManager() public view returns (contract ITokenManager) ``` -Getter for the contract id. +Getter for the tokenManager used for this token. -### standardizedTokenSalt +_Needs to be overwritten._ -```solidity -function standardizedTokenSalt(bytes32 chainNameHash_, address deployer, bytes32 salt) public pure returns (bytes32) -``` +#### Return Values -### standardizedTokenId +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | contract ITokenManager | | + +### _beforeInterchainTransfer ```solidity -function standardizedTokenId(address deployer, bytes32 salt) public view returns (bytes32 tokenId) +function _beforeInterchainTransfer(address sender, string, bytes, uint256 amount, bytes) internal ``` -### interchainTokenAddress +### setTokenManagerRequiresApproval ```solidity -function interchainTokenAddress(address deployer, bytes32 salt) public view returns (address tokenAddress) +function setTokenManagerRequiresApproval(bool requiresApproval) public ``` -### deployInterchainToken +### mint ```solidity -function deployInterchainToken(bytes32 salt, string name, string symbol, uint8 decimals, uint256 mintAmount, address distributor, address operator) external payable +function mint(address account, uint256 amount) external ``` -### deployRemoteInterchainToken +### burn ```solidity -function deployRemoteInterchainToken(string originalChainName, bytes32 salt, address additionalDistributor, address optionalOperator, string destinationChain, uint256 gasValue) external payable +function burn(address account, uint256 amount) external ``` -### _deployInterchainToken +### setTokenManager ```solidity -function _deployInterchainToken(bytes32 salt, string destinationChain, string tokenName, string tokenSymbol, uint8 tokenDecimals, bytes distributor, bytes operator, uint256 gasValue) internal +function setTokenManager(contract ITokenManager tokenManagerAddress) external ``` -### canonicalTokenSalt +### _transfer ```solidity -function canonicalTokenSalt(bytes32 chainNameHash_, address tokenAddress) public pure returns (bytes32 salt) +function _transfer(address sender, address recipient, uint256 amount) internal ``` -### canonicalTokenId +_Moves tokens `amount` from `sender` to `recipient`. -```solidity -function canonicalTokenId(address tokenAddress) public view returns (bytes32 tokenId) -``` +This is internal function is equivalent to {transfer}, and can be used to +e.g. implement automatic token fees, slashing mechanisms, etc. -### registerCanonicalToken +Emits a {Transfer} event. -```solidity -function registerCanonicalToken(address tokenAddress) external payable returns (bytes32 tokenId) -``` +Requirements: -### deployRemoteCanonicalToken +- `sender` cannot be the zero address. +- `recipient` cannot be the zero address. +- `sender` must have a balance of at least `amount`._ + +## Invalid ```solidity -function deployRemoteCanonicalToken(string originalChain, address originalTokenAddress, string destinationChain, uint256 gasValue) external payable +error Invalid() ``` -### interchainTransfer +## TestTokenManager + +### NAME ```solidity -function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable +string NAME ``` -### interchainTransferFrom +### constructor ```solidity -function interchainTransferFrom(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable +constructor(address interchainTokenService_) public ``` -## Distributable - -_A contract module which provides a basic access control mechanism, where -there is an account (a distributor) that can be granted exclusive access to -specific functions. This module is used through inheritance._ +## TestDistributable -### _addDistributor +### NAME ```solidity -function _addDistributor(address distributor_) internal +string NAME ``` -_Internal function that stores the new distributor address in the correct storage slot_ +### constructor -#### Parameters +```solidity +constructor() public +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| distributor_ | address | The address of the new distributor | +## TestFlowLimit -### transferDistributorship +### NAME ```solidity -function transferDistributorship(address distributor_) external +string NAME ``` -Change the distributor of the contract - -_Can only be called by the current distributor_ +### constructor -#### Parameters +```solidity +constructor() public +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| distributor_ | address | The address of the new distributor | +## TestOperatable -### proposeDistributorship +### NAME ```solidity -function proposeDistributorship(address distributor_) external +string NAME ``` -Proposed a change of the distributor of the contract - -_Can only be called by the current distributor_ +### constructor -#### Parameters +```solidity +constructor() public +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| distributor_ | address | The address of the new distributor | +## InterchainExecutableTest -### acceptDistributorship +### MessageReceived ```solidity -function acceptDistributorship(address fromDistributor) external +event MessageReceived(string sourceChain, bytes sourceAddress, address receiver, string message, bytes32 tokenId, uint256 amount) ``` -Accept a change of the distributor of the contract +### constructor -_Can only be called by the proposed distributor_ +```solidity +constructor(address interchainTokenService_) public +``` -### isDistributor +### lastMessage ```solidity -function isDistributor(address addr) external view returns (bool) +string lastMessage ``` -Query if an address is a distributor +### _executeWithInterchainToken -#### Parameters +```solidity +function _executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) internal +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| addr | address | the address to query for | +## InterchainTokenTest -## FlowLimit +### tokenManager_ -Implements flow limit logic for interchain token transfers. +```solidity +contract ITokenManager tokenManager_ +``` -_This contract implements low-level assembly for optimization purposes._ +### tokenManagerRequiresApproval_ -### FLOW_LIMIT_SLOT +```solidity +bool tokenManagerRequiresApproval_ +``` + +### name ```solidity -uint256 FLOW_LIMIT_SLOT +string name ``` -### PREFIX_FLOW_OUT_AMOUNT +### symbol ```solidity -uint256 PREFIX_FLOW_OUT_AMOUNT +string symbol ``` -### PREFIX_FLOW_IN_AMOUNT +### decimals ```solidity -uint256 PREFIX_FLOW_IN_AMOUNT +uint8 decimals ``` -### EPOCH_TIME +### constructor ```solidity -uint256 EPOCH_TIME +constructor(string name_, string symbol_, uint8 decimals_, address tokenManagerAddress) public ``` -### flowLimit +### tokenManager ```solidity -function flowLimit() public view returns (uint256 flowLimit_) +function tokenManager() public view returns (contract ITokenManager) ``` -Returns the current flow limit +Getter for the tokenManager used for this token. + +_Needs to be overwritten._ #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| flowLimit_ | uint256 | The current flow limit value | +| [0] | contract ITokenManager | | -### _setFlowLimit +### _beforeInterchainTransfer ```solidity -function _setFlowLimit(uint256 flowLimit_, bytes32 tokenId) internal +function _beforeInterchainTransfer(address sender, string, bytes, uint256 amount, bytes) internal ``` -_Internal function to set the flow limit_ - -#### Parameters +### setTokenManagerRequiresApproval -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowLimit_ | uint256 | The value to set the flow limit to | -| tokenId | bytes32 | | +```solidity +function setTokenManagerRequiresApproval(bool requiresApproval) public +``` -### _getFlowOutSlot +### mint ```solidity -function _getFlowOutSlot(uint256 epoch) internal pure returns (uint256 slot) +function mint(address account, uint256 amount) external ``` -_Returns the slot which is used to get the flow out amount for a specific epoch_ +### burn -#### Parameters +```solidity +function burn(address account, uint256 amount) external +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| epoch | uint256 | The epoch to get the flow out amount for | +### setTokenManager -#### Return Values +```solidity +function setTokenManager(contract ITokenManager tokenManagerAddress) external +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| slot | uint256 | The slot to get the flow out amount from | +## InvalidStandardizedToken -### _getFlowInSlot +### name ```solidity -function _getFlowInSlot(uint256 epoch) internal pure returns (uint256 slot) +string name ``` -_Returns the slot which is used to get the flow in amount for a specific epoch_ - -#### Parameters +### symbol -| Name | Type | Description | -| ---- | ---- | ----------- | -| epoch | uint256 | The epoch to get the flow in amount for | +```solidity +string symbol +``` -#### Return Values +### decimals -| Name | Type | Description | -| ---- | ---- | ----------- | -| slot | uint256 | The slot to get the flow in amount from | +```solidity +uint8 decimals +``` -### flowOutAmount +### tokenManager_ ```solidity -function flowOutAmount() external view returns (uint256 flowOutAmount_) +address tokenManager_ ``` -Returns the current flow out amount +### contractId -#### Return Values +```solidity +function contractId() external pure returns (bytes32) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| flowOutAmount_ | uint256 | The current flow out amount | +Getter for the contract id. -### flowInAmount +### tokenManager ```solidity -function flowInAmount() external view returns (uint256 flowInAmount_) +function tokenManager() public view returns (contract ITokenManager) ``` -Returns the current flow in amount +Returns the token manager for this token #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| flowInAmount_ | uint256 | The current flow in amount | +| [0] | contract ITokenManager | ITokenManager The token manager contract | -### _addFlow +### setup ```solidity -function _addFlow(uint256 flowLimit_, uint256 slotToAdd, uint256 slotToCompare, uint256 flowAmount) internal +function setup(bytes params) external ``` -_Adds a flow amount while ensuring it does not exceed the flow limit_ +Setup function to initialize contract parameters #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowLimit_ | uint256 | The current flow limit value | -| slotToAdd | uint256 | The slot to add the flow to | -| slotToCompare | uint256 | The slot to compare the flow against | -| flowAmount | uint256 | The flow amount to add | +| params | bytes | The setup parameters in bytes The setup params include tokenManager, distributor, tokenName, symbol, decimals, mintAmount and mintTo | -### _addFlowOut +### mint ```solidity -function _addFlowOut(uint256 flowOutAmount_) internal +function mint(address account, uint256 amount) external ``` -_Adds a flow out amount_ +Function to mint new tokens +Can only be called by the distributor address. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowOutAmount_ | uint256 | The flow out amount to add | +| account | address | The address that will receive the minted tokens | +| amount | uint256 | The amount of tokens to mint | -### _addFlowIn +### burn ```solidity -function _addFlowIn(uint256 flowInAmount_) internal +function burn(address account, uint256 amount) external ``` -_Adds a flow in amount_ +Function to burn tokens +Can only be called by the distributor address. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| flowInAmount_ | uint256 | The flow in amount to add | +| account | address | The address that will have its tokens burnt | +| amount | uint256 | The amount of tokens to burn | -## Implementation +## DistributableTest -This contract serves as a base for other contracts and enforces a proxy-first access restriction. +### nonce -_Derived contracts must implement the setup function._ +```solidity +uint256 nonce +``` ### constructor ```solidity -constructor() internal +constructor(address distributor) public ``` -_Contract constructor that sets the implementation address to the address of this contract._ - -### onlyProxy +### testDistributable ```solidity -modifier onlyProxy() +function testDistributable() external ``` -_Modifier to require the caller to be the proxy contract. -Reverts if the caller is the current contract (i.e., the implementation contract itself)._ +### distributorRole -## Operatable +```solidity +function distributorRole() external pure returns (uint8) +``` -_A contract module which provides a basic access control mechanism, where -there is an account (a operator) that can be granted exclusive access to -specific functions. This module is used through inheritance._ +## FlowLimitTest -### _addOperator +### TOKEN_ID ```solidity -function _addOperator(address operator_) internal +bytes32 TOKEN_ID ``` -_Internal function that stores the new operator address in the correct storage slot_ - -#### Parameters +### setFlowLimit -| Name | Type | Description | -| ---- | ---- | ----------- | -| operator_ | address | The address of the new operator | +```solidity +function setFlowLimit(uint256 flowLimit) external +``` -### transferOperatorship +### addFlowIn ```solidity -function transferOperatorship(address operator_) external +function addFlowIn(uint256 flowInAmount) external ``` -Change the operator of the contract - -_Can only be called by the current operator_ +### addFlowOut -#### Parameters +```solidity +function addFlowOut(uint256 flowOutAmount) external +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| operator_ | address | The address of the new operator | +## FlowLimitTestLiveNetwork -### proposeOperatorship +### FLOW_LIMIT_SLOT ```solidity -function proposeOperatorship(address operator_) external +uint256 FLOW_LIMIT_SLOT ``` -Proposed a change of the operator of the contract +### PREFIX_FLOW_OUT_AMOUNT -_Can only be called by the current operator_ +```solidity +uint256 PREFIX_FLOW_OUT_AMOUNT +``` -#### Parameters +### PREFIX_FLOW_IN_AMOUNT -| Name | Type | Description | -| ---- | ---- | ----------- | -| operator_ | address | The address of the new operator | +```solidity +uint256 PREFIX_FLOW_IN_AMOUNT +``` -### acceptOperatorship +### TOKEN_ID ```solidity -function acceptOperatorship(address fromOperator) external +bytes32 TOKEN_ID ``` -Accept a change of the operator of the contract +### EPOCH_TIME -_Can only be called by the proposed operator_ +```solidity +uint256 EPOCH_TIME +``` -### isOperator +### flowLimit ```solidity -function isOperator(address addr) external view returns (bool) +function flowLimit() public view returns (uint256 flowLimit_) ``` -Query if an address is an operator +Returns the current flow limit -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| addr | address | the address to query for | - -## RolesConstants +| flowLimit_ | uint256 | The current flow limit value | -### Roles +### _setFlowLimit ```solidity -enum Roles { - DISTRIBUTOR, - OPERATOR, - FLOW_LIMITER -} +function _setFlowLimit(uint256 flowLimit_) internal ``` -## TokenManagerDeployer +### _getFlowOutSlot -This contract is used to deploy new instances of the TokenManagerProxy contract. +```solidity +function _getFlowOutSlot(uint256 epoch) internal pure returns (uint256 slot) +``` -### deployTokenManager +### _getFlowInSlot ```solidity -function deployTokenManager(bytes32 tokenId, uint256 implementationType, bytes params) external payable returns (address tokenManager) +function _getFlowInSlot(uint256 epoch) internal pure returns (uint256 slot) ``` -Deploys a new instance of the TokenManagerProxy contract +### flowOutAmount -#### Parameters +```solidity +function flowOutAmount() external view returns (uint256 flowOutAmount_) +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| tokenId | bytes32 | The unique identifier for the token | -| implementationType | uint256 | Token manager implementation type | -| params | bytes | Additional parameters used in the setup of the token manager | +Returns the current flow out amount #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenManager | address | The address of the deployed tokenManager | - -## InterchainToken - -The implementation ERC20 can be done in any way, however this example assumes that an _approve internal function exists -that can be used to create approvals, and that `allowance` is a mapping. +| flowOutAmount_ | uint256 | The current flow out amount | -### tokenManager +### flowInAmount ```solidity -function tokenManager() public view virtual returns (contract ITokenManager tokenManager_) +function flowInAmount() external view returns (uint256 flowInAmount_) ``` -Getter for the tokenManager used for this token. - -_Needs to be overwritten._ +Returns the current flow in amount #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenManager_ | contract ITokenManager | the TokenManager called to facilitate cross chain transfers. | +| flowInAmount_ | uint256 | The current flow in amount | -### interchainTransfer +### _addFlow ```solidity -function interchainTransfer(string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable +function _addFlow(uint256 flowLimit_, uint256 slotToAdd, uint256 slotToCompare, uint256 flowAmount) internal ``` -Implementation of the interchainTransfer method - -_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. -A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ +### _addFlowOut -#### Parameters +```solidity +function _addFlowOut(uint256 flowOutAmount_) internal +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| destinationChain | string | The destination chain identifier. | -| recipient | bytes | The bytes representation of the address of the recipient. | -| amount | uint256 | The amount of token to be transferred. | -| metadata | bytes | Either empty, to just facilitate an interchain transfer, or the data can be passed for an interchain contract call with transfer as per semantics defined by the token service. | - -### interchainTransferFrom +### _addFlowIn ```solidity -function interchainTransferFrom(address sender, string destinationChain, bytes recipient, uint256 amount, bytes metadata) external payable +function _addFlowIn(uint256 flowInAmount_) internal ``` -Implementation of the interchainTransferFrom method - -_We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer. -A different implementation could have `metadata` that tells this function which function to use or that it is used for anything else as well._ - -#### Parameters +### setFlowLimit -| Name | Type | Description | -| ---- | ---- | ----------- | -| sender | address | the sender of the tokens. They need to have approved `msg.sender` before this is called. | -| destinationChain | string | the string representation of the destination chain. | -| recipient | bytes | the bytes representation of the address of the recipient. | -| amount | uint256 | the amount of token to be transferred. | -| metadata | bytes | either empty, to just facilitate a cross-chain transfer, or the data to be passed to a cross-chain contract call and transfer. | +```solidity +function setFlowLimit(uint256 flowLimit_) external +``` -### _beforeInterchainTransfer +### addFlowIn ```solidity -function _beforeInterchainTransfer(address from, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) internal virtual +function addFlowIn(uint256 flowInAmount_) external ``` -A method to be overwritten that will be called before an interchain transfer. You can approve the tokenManager here if you need and want to, to allow users for a 1-call transfer in case of a lock-unlock token manager. +### addFlowOut -#### Parameters +```solidity +function addFlowOut(uint256 flowOutAmount_) external +``` -| Name | Type | Description | -| ---- | ---- | ----------- | -| from | address | the sender of the tokens. They need to have approved `msg.sender` before this is called. | -| destinationChain | string | the string representation of the destination chain. | -| destinationAddress | bytes | the bytes representation of the address of the recipient. | -| amount | uint256 | the amount of token to be transferred. | -| metadata | bytes | either empty, to just facilitate a cross-chain transfer, or the data to be passed to a cross-chain contract call and transfer. | +## ImplementationTest -## ITokenManagerLockUnlockFee +### val -This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. +```solidity +uint256 val +``` -### params +### setup ```solidity -function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) +function setup(bytes params) external ``` -Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. - -#### Parameters +Called by the proxy to setup itself. -| Name | Type | Description | -| ---- | ---- | ----------- | -| operator_ | bytes | the operator of the TokenManager. | -| tokenAddress_ | address | the token to be managed. | +_This should be hidden by the proxy._ -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | - -## StandardizedTokenProxy +| params | bytes | the data to be used for the initialization. | -_Proxy contract for StandardizedToken contracts. Inherits from FixedProxy._ +## NakedProxy -### constructor +### implementation ```solidity -constructor(address implementationAddress, bytes params) public +address implementation ``` -_Constructs the StandardizedTokenProxy contract._ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| implementationAddress | address | Address of the StandardizedToken implementation | -| params | bytes | Initialization parameters for the StandardizedToken contract | - -### contractId +### constructor ```solidity -function contractId() internal pure returns (bytes32) +constructor(address implementation_) public ``` -Getter for the contract id. - -## FeeOnTransferTokenTest - -### tokenManager_ +### fallback ```solidity -contract ITokenManager tokenManager_ +fallback() external payable virtual ``` -### tokenManagerRequiresApproval_ +### receive ```solidity -bool tokenManagerRequiresApproval_ +receive() external payable virtual ``` -### name +## OperatorableTest + +### nonce ```solidity -string name +uint256 nonce ``` -### symbol +### constructor ```solidity -string symbol +constructor(address operator) public ``` -### decimals +### testOperatorable ```solidity -uint8 decimals +function testOperatorable() external ``` -### constructor +### operatorRole ```solidity -constructor(string name_, string symbol_, uint8 decimals_, address tokenManagerAddress) public +function operatorRole() external pure returns (uint8) ``` -### tokenManager +## ERC20 -```solidity -function tokenManager() public view returns (contract ITokenManager) -``` +_Implementation of the {IERC20} interface. -Getter for the tokenManager used for this token. +This implementation is agnostic to the way tokens are created. This means +that a supply mechanism has to be added in a derived contract using {_mint}. +For a generic mechanism see {ERC20PresetMinterPauser}. -_Needs to be overwritten._ +TIP: For a detailed writeup see our guide +https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How +to implement supply mechanisms]. -#### Return Values +We have followed general OpenZeppelin guidelines: functions revert instead +of returning `false` on failure. This behavior is nonetheless conventional +and does not conflict with the expectations of ERC20 applications. -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | contract ITokenManager | | +Additionally, an {Approval} event is emitted on calls to {transferFrom}. +This allows applications to reconstruct the allowance for all accounts just +by listening to said events. Other implementations of the EIP may not emit +these events, as it isn't required by the specification. -### _beforeInterchainTransfer +Finally, the non-standard {decreaseAllowance} and {increaseAllowance} +functions have been added to mitigate the well-known issues around setting +allowances. See {IERC20-approve}._ + +### balanceOf ```solidity -function _beforeInterchainTransfer(address sender, string, bytes, uint256 amount, bytes) internal +mapping(address => uint256) balanceOf ``` -### setTokenManagerRequiresApproval +_Returns the amount of tokens owned by `account`._ + +### allowance ```solidity -function setTokenManagerRequiresApproval(bool requiresApproval) public +mapping(address => mapping(address => uint256)) allowance ``` -### mint +_Returns the remaining number of tokens that `spender` will be +allowed to spend on behalf of `owner` through {transferFrom}. This is +zero by default. -```solidity -function mint(address account, uint256 amount) external -``` +This value changes when {approve} or {transferFrom} are called._ -### burn +### totalSupply ```solidity -function burn(address account, uint256 amount) external +uint256 totalSupply ``` -### setTokenManager +_Returns the amount of tokens in existence._ + +### UINT256_MAX ```solidity -function setTokenManager(contract ITokenManager tokenManagerAddress) external +uint256 UINT256_MAX ``` -### _transfer +### transfer ```solidity -function _transfer(address sender, address recipient, uint256 amount) internal +function transfer(address recipient, uint256 amount) external virtual returns (bool) ``` -_Moves tokens `amount` from `sender` to `recipient`. - -This is internal function is equivalent to {transfer}, and can be used to -e.g. implement automatic token fees, slashing mechanisms, etc. - -Emits a {Transfer} event. +_See {IERC20-transfer}. Requirements: -- `sender` cannot be the zero address. - `recipient` cannot be the zero address. -- `sender` must have a balance of at least `amount`._ - -## InterchainTokenTest +- the caller must have a balance of at least `amount`._ -### tokenManager_ +### approve ```solidity -contract ITokenManager tokenManager_ +function approve(address spender, uint256 amount) external virtual returns (bool) ``` -### tokenManagerRequiresApproval_ +_See {IERC20-approve}. -```solidity -bool tokenManagerRequiresApproval_ -``` +NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on +`transferFrom`. This is semantically equivalent to an infinite approval. -### name +Requirements: -```solidity -string name -``` +- `spender` cannot be the zero address._ -### symbol +### transferFrom ```solidity -string symbol +function transferFrom(address sender, address recipient, uint256 amount) external virtual returns (bool) ``` -### decimals +_See {IERC20-transferFrom}. -```solidity -uint8 decimals -``` +Emits an {Approval} event indicating the updated allowance. This is not +required by the EIP. See the note at the beginning of {ERC20}. -### constructor +Requirements: -```solidity -constructor(string name_, string symbol_, uint8 decimals_, address tokenManagerAddress) public -``` +- `sender` and `recipient` cannot be the zero address. +- `sender` must have a balance of at least `amount`. +- the caller must have allowance for ``sender``'s tokens of at least +`amount`._ -### tokenManager +### increaseAllowance ```solidity -function tokenManager() public view returns (contract ITokenManager) +function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) ``` -Getter for the tokenManager used for this token. - -_Needs to be overwritten._ +_Atomically increases the allowance granted to `spender` by the caller. -#### Return Values +This is an alternative to {approve} that can be used as a mitigation for +problems described in {IERC20-approve}. -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | contract ITokenManager | | +Emits an {Approval} event indicating the updated allowance. -### _beforeInterchainTransfer +Requirements: -```solidity -function _beforeInterchainTransfer(address sender, string, bytes, uint256 amount, bytes) internal -``` +- `spender` cannot be the zero address._ -### setTokenManagerRequiresApproval +### decreaseAllowance ```solidity -function setTokenManagerRequiresApproval(bool requiresApproval) public +function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool) ``` -### mint +_Atomically decreases the allowance granted to `spender` by the caller. -```solidity -function mint(address account, uint256 amount) external -``` +This is an alternative to {approve} that can be used as a mitigation for +problems described in {IERC20-approve}. -### burn +Emits an {Approval} event indicating the updated allowance. + +Requirements: + +- `spender` cannot be the zero address. +- `spender` must have allowance for the caller of at least +`subtractedValue`._ + +### _transfer ```solidity -function burn(address account, uint256 amount) external +function _transfer(address sender, address recipient, uint256 amount) internal virtual ``` -### setTokenManager +_Moves tokens `amount` from `sender` to `recipient`. + +This is internal function is equivalent to {transfer}, and can be used to +e.g. implement automatic token fees, slashing mechanisms, etc. + +Emits a {Transfer} event. + +Requirements: + +- `sender` cannot be the zero address. +- `recipient` cannot be the zero address. +- `sender` must have a balance of at least `amount`._ + +### _mint ```solidity -function setTokenManager(contract ITokenManager tokenManagerAddress) external +function _mint(address account, uint256 amount) internal virtual ``` -## InvalidStandardizedToken +_Creates `amount` tokens and assigns them to `account`, increasing +the total supply. + +Emits a {Transfer} event with `from` set to the zero address. + +Requirements: + +- `to` cannot be the zero address._ + +### _burn + +```solidity +function _burn(address account, uint256 amount) internal virtual +``` + +_Destroys `amount` tokens from `account`, reducing the +total supply. + +Emits a {Transfer} event with `to` set to the zero address. + +Requirements: + +- `account` cannot be the zero address. +- `account` must have at least `amount` tokens._ + +### _approve + +```solidity +function _approve(address owner, address spender, uint256 amount) internal virtual +``` + +_Sets `amount` as the allowance of `spender` over the `owner` s tokens. + +This internal function is equivalent to `approve`, and can be used to +e.g. set automatic allowances for certain subsystems, etc. + +Emits an {Approval} event. + +Requirements: + +- `owner` cannot be the zero address. +- `spender` cannot be the zero address._ + +## ERC20Permit + +_Extension of ERC20 to include permit functionality (EIP-2612). +Allows for approval of ERC20 tokens by signature rather than transaction._ + +### PermitExpired + +```solidity +error PermitExpired() +``` + +### InvalidS + +```solidity +error InvalidS() +``` + +### InvalidV + +```solidity +error InvalidV() +``` + +### InvalidSignature + +```solidity +error InvalidSignature() +``` + +### nameHash + +```solidity +bytes32 nameHash +``` + +_Represents hash of the EIP-712 Domain Separator._ + +### nonces + +```solidity +mapping(address => uint256) nonces +``` + +_Mapping of nonces for each address._ + +### _setNameHash + +```solidity +function _setNameHash(string name) internal +``` + +Internal function to set the token name hash + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| name | string | The token name | + +### DOMAIN_SEPARATOR + +```solidity +function DOMAIN_SEPARATOR() public view returns (bytes32) +``` + +Calculates the domain separator. + +_This is not cached because chainid can change on chain forks._ + +### permit + +```solidity +function permit(address issuer, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external +``` + +Permit the designated spender to spend the holder's tokens + +_The permit function is used to allow a holder to designate a spender +to spend tokens on their behalf via a signed message._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| issuer | address | The address of the token holder | +| spender | address | The address of the designated spender | +| value | uint256 | The number of tokens to be spent | +| deadline | uint256 | The time at which the permission to spend expires | +| v | uint8 | The recovery id of the signature | +| r | bytes32 | Half of the ECDSA signature pair | +| s | bytes32 | Half of the ECDSA signature pair | + +## StandardizedToken + +This contract implements a standardized token which extends InterchainToken functionality. +This contract also inherits Distributable and Implementation logic. ### name @@ -4075,18 +3883,24 @@ function setTokenManager(contract ITokenManager tokenManagerAddress) external string name ``` +Getter for the name of the token + ### symbol ```solidity string symbol ``` +Getter for the symbol of the token + ### decimals ```solidity uint8 decimals ``` +Getter for the decimals of the token + ### tokenManager_ ```solidity @@ -4161,1028 +3975,1033 @@ Can only be called by the distributor address. | account | address | The address that will have its tokens burnt | | amount | uint256 | The amount of tokens to burn | -## ERC20 +## TokenManager -_Implementation of the {IERC20} interface. +This contract is responsible for handling tokens before initiating a cross chain token transfer, or after receiving one. -This implementation is agnostic to the way tokens are created. This means -that a supply mechanism has to be added in a derived contract using {_mint}. -For a generic mechanism see {ERC20PresetMinterPauser}. +### interchainTokenService -TIP: For a detailed writeup see our guide -https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How -to implement supply mechanisms]. +```solidity +contract IInterchainTokenService interchainTokenService +``` -We have followed general OpenZeppelin guidelines: functions revert instead -of returning `false` on failure. This behavior is nonetheless conventional -and does not conflict with the expectations of ERC20 applications. +### TOKEN_ADDRESS_SLOT -Additionally, an {Approval} event is emitted on calls to {transferFrom}. -This allows applications to reconstruct the allowance for all accounts just -by listening to said events. Other implementations of the EIP may not emit -these events, as it isn't required by the specification. +```solidity +uint256 TOKEN_ADDRESS_SLOT +``` -Finally, the non-standard {decreaseAllowance} and {increaseAllowance} -functions have been added to mitigate the well-known issues around setting -allowances. See {IERC20-approve}._ +### constructor -### balanceOf +```solidity +constructor(address interchainTokenService_) internal +``` + +Constructs the TokenManager contract. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| interchainTokenService_ | address | The address of the interchain token service | + +### onlyService ```solidity -mapping(address => uint256) balanceOf +modifier onlyService() ``` -_Returns the amount of tokens owned by `account`._ +_A modifier that allows only the interchain token service to execute the function._ -### allowance +### onlyToken ```solidity -mapping(address => mapping(address => uint256)) allowance +modifier onlyToken() ``` -_Returns the remaining number of tokens that `spender` will be -allowed to spend on behalf of `owner` through {transferFrom}. This is -zero by default. +_A modifier that allows only the token to execute the function._ -This value changes when {approve} or {transferFrom} are called._ +### tokenAddress -### totalSupply +```solidity +function tokenAddress() public view virtual returns (address tokenAddress_) +``` + +_Reads the stored token address from the predetermined storage slot_ + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress_ | address | The address of the token | + +### interchainTokenId ```solidity -uint256 totalSupply +function interchainTokenId() public view returns (bytes32) ``` -_Returns the amount of tokens in existence._ +A function that returns the token id. -### UINT256_MAX +_This will only work when implementation is called by a proxy, which stores the tokenId as an immutable._ + +### setup ```solidity -uint256 UINT256_MAX +function setup(bytes params) external ``` -### transfer +_This function should only be called by the proxy, and only once from the proxy constructor_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| params | bytes | the parameters to be used to initialize the TokenManager. The exact format depends on the type of TokenManager used but the first 32 bytes are reserved for the address of the operator, stored as bytes (to be compatible with non-EVM chains) | + +### interchainTransfer ```solidity -function transfer(address recipient, uint256 amount) external virtual returns (bool) +function interchainTransfer(string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable virtual ``` -_See {IERC20-transfer}. +Calls the service to initiate a cross-chain transfer after taking the appropriate amount of tokens from the user. -Requirements: +#### Parameters -- `recipient` cannot be the zero address. -- the caller must have a balance of at least `amount`._ +| Name | Type | Description | +| ---- | ---- | ----------- | +| destinationChain | string | the name of the chain to send tokens to. | +| destinationAddress | bytes | the address of the user to send tokens to. | +| amount | uint256 | the amount of tokens to take from msg.sender. | +| metadata | bytes | any additional data to be sent with the transfer. | -### approve +### callContractWithInterchainToken ```solidity -function approve(address spender, uint256 amount) external virtual returns (bool) +function callContractWithInterchainToken(string destinationChain, bytes destinationAddress, uint256 amount, bytes data) external payable virtual ``` -_See {IERC20-approve}. +Calls the service to initiate a cross-chain transfer with data after taking the appropriate amount of tokens from the user. -NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on -`transferFrom`. This is semantically equivalent to an infinite approval. +#### Parameters -Requirements: +| Name | Type | Description | +| ---- | ---- | ----------- | +| destinationChain | string | the name of the chain to send tokens to. | +| destinationAddress | bytes | the address of the user to send tokens to. | +| amount | uint256 | the amount of tokens to take from msg.sender. | +| data | bytes | the data to pass to the destination contract. | -- `spender` cannot be the zero address._ +### transmitInterchainTransfer -### transferFrom +```solidity +function transmitInterchainTransfer(address sender, string destinationChain, bytes destinationAddress, uint256 amount, bytes metadata) external payable virtual +``` + +Calls the service to initiate a cross-chain transfer after taking the appropriate amount of tokens from the user. This can only be called by the token itself. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| sender | address | the address of the user paying for the cross chain transfer. | +| destinationChain | string | the name of the chain to send tokens to. | +| destinationAddress | bytes | the address of the user to send tokens to. | +| amount | uint256 | the amount of tokens to take from msg.sender. | +| metadata | bytes | any additional data to be sent with the transfer | + +### giveToken ```solidity -function transferFrom(address sender, address recipient, uint256 amount) external virtual returns (bool) +function giveToken(address destinationAddress, uint256 amount) external returns (uint256) ``` -_See {IERC20-transferFrom}. +This function gives token to a specified address. Can only be called by the service. -Emits an {Approval} event indicating the updated allowance. This is not -required by the EIP. See the note at the beginning of {ERC20}. +#### Parameters -Requirements: +| Name | Type | Description | +| ---- | ---- | ----------- | +| destinationAddress | address | the address to give tokens to. | +| amount | uint256 | the amount of token to give. | -- `sender` and `recipient` cannot be the zero address. -- `sender` must have a balance of at least `amount`. -- the caller must have allowance for ``sender``'s tokens of at least -`amount`._ +#### Return Values -### increaseAllowance +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | the amount of token actually given, which will only be different than `amount` in cases where the token takes some on-transfer fee. | + +### takeToken ```solidity -function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) +function takeToken(address sourceAddress, uint256 amount) external returns (uint256) ``` -_Atomically increases the allowance granted to `spender` by the caller. +This function gives token to a specified address. Can only be called by the service. -This is an alternative to {approve} that can be used as a mitigation for -problems described in {IERC20-approve}. +#### Parameters -Emits an {Approval} event indicating the updated allowance. +| Name | Type | Description | +| ---- | ---- | ----------- | +| sourceAddress | address | the address to give tokens to. | +| amount | uint256 | the amount of token to give. | -Requirements: +#### Return Values -- `spender` cannot be the zero address._ +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | the amount of token actually given, which will onle be differen than `amount` in cases where the token takes some on-transfer fee. | -### decreaseAllowance +### addFlowLimiter ```solidity -function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool) +function addFlowLimiter(address flowLimiter) external ``` -_Atomically decreases the allowance granted to `spender` by the caller. +This function adds a flow limiter for this TokenManager. Can only be called by the operator. -This is an alternative to {approve} that can be used as a mitigation for -problems described in {IERC20-approve}. +#### Parameters -Emits an {Approval} event indicating the updated allowance. +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowLimiter | address | the address of the new flow limiter. | -Requirements: +### removeFlowLimiter -- `spender` cannot be the zero address. -- `spender` must have allowance for the caller of at least -`subtractedValue`._ +```solidity +function removeFlowLimiter(address flowLimiter) external +``` -### _transfer +This function removes a flow limiter for this TokenManager. Can only be called by the operator. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowLimiter | address | the address of an existing flow limiter. | + +### setFlowLimit ```solidity -function _transfer(address sender, address recipient, uint256 amount) internal virtual +function setFlowLimit(uint256 flowLimit_) external ``` -_Moves tokens `amount` from `sender` to `recipient`. +This function sets the flow limit for this TokenManager. Can only be called by the flow limiters. -This is internal function is equivalent to {transfer}, and can be used to -e.g. implement automatic token fees, slashing mechanisms, etc. +#### Parameters -Emits a {Transfer} event. +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowLimit_ | uint256 | the maximum difference between the tokens flowing in and/or out at any given interval of time (6h) | -Requirements: +### _setTokenAddress -- `sender` cannot be the zero address. -- `recipient` cannot be the zero address. -- `sender` must have a balance of at least `amount`._ +```solidity +function _setTokenAddress(address tokenAddress_) internal +``` -### _mint +_Stores the token address in the predetermined storage slot_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress_ | address | The address of the token to store | + +### _takeToken ```solidity -function _mint(address account, uint256 amount) internal virtual +function _takeToken(address from, uint256 amount) internal virtual returns (uint256) ``` -_Creates `amount` tokens and assigns them to `account`, increasing -the total supply. +Transfers tokens from a specific address to this contract. +Must be overridden in the inheriting contract. -Emits a {Transfer} event with `from` set to the zero address. +#### Parameters -Requirements: +| Name | Type | Description | +| ---- | ---- | ----------- | +| from | address | The address from which the tokens will be sent | +| amount | uint256 | The amount of tokens to receive | -- `to` cannot be the zero address._ +#### Return Values -### _burn +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint amount of tokens received | + +### _giveToken ```solidity -function _burn(address account, uint256 amount) internal virtual +function _giveToken(address receiver, uint256 amount) internal virtual returns (uint256) ``` -_Destroys `amount` tokens from `account`, reducing the -total supply. +Transfers tokens from this contract to a specific address. +Must be overridden in the inheriting contract. -Emits a {Transfer} event with `to` set to the zero address. +#### Parameters -Requirements: +| Name | Type | Description | +| ---- | ---- | ----------- | +| receiver | address | The address to which the tokens will be sent | +| amount | uint256 | The amount of tokens to send | -- `account` cannot be the zero address. -- `account` must have at least `amount` tokens._ +#### Return Values -### _approve +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint amount of tokens sent | + +### _setup ```solidity -function _approve(address owner, address spender, uint256 amount) internal virtual +function _setup(bytes params) internal virtual ``` -_Sets `amount` as the allowance of `spender` over the `owner` s tokens. - -This internal function is equivalent to `approve`, and can be used to -e.g. set automatic allowances for certain subsystems, etc. +_Additional setup logic to perform +Must be overridden in the inheriting contract._ -Emits an {Approval} event. +#### Parameters -Requirements: +| Name | Type | Description | +| ---- | ---- | ----------- | +| params | bytes | The setup parameters | -- `owner` cannot be the zero address. -- `spender` cannot be the zero address._ +## TokenManagerLiquidityPool -## ERC20Permit +This contract is a an implementation of TokenManager that stores all tokens in a separate liquity pool +rather than within itself. -_Extension of ERC20 to include permit functionality (EIP-2612). -Allows for approval of ERC20 tokens by signature rather than transaction._ +_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. +It uses the Axelar SDK to safely transfer tokens._ -### PermitExpired +### NotSupported ```solidity -error PermitExpired() +error NotSupported() ``` -### InvalidS +### LIQUIDITY_POOL_SLOT ```solidity -error InvalidS() +uint256 LIQUIDITY_POOL_SLOT ``` -### InvalidV +### constructor ```solidity -error InvalidV() +constructor(address interchainTokenService_) public ``` -### InvalidSignature +_Constructs an instance of TokenManagerLiquidityPool. Calls the constructor +of TokenManagerAddressStorage which calls the constructor of TokenManager._ -```solidity -error InvalidSignature() -``` +#### Parameters -### nameHash +| Name | Type | Description | +| ---- | ---- | ----------- | +| interchainTokenService_ | address | The address of the interchain token service contract | + +### implementationType ```solidity -bytes32 nameHash +function implementationType() external pure returns (uint256) ``` -_Represents hash of the EIP-712 Domain Separator._ +A function that should return the implementation type of the token manager. -### nonces +### _setup ```solidity -mapping(address => uint256) nonces +function _setup(bytes params_) internal ``` -_Mapping of nonces for each address._ +_Sets up the token address and liquidity pool address._ -### _setNameHash +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address and the liquidity pool address. | + +### _setLiquidityPool ```solidity -function _setNameHash(string name) internal +function _setLiquidityPool(address liquidityPool_) internal ``` -Internal function to set the token name hash +_Stores the liquidity pool address at a specific storage slot_ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| name | string | The token name | +| liquidityPool_ | address | The address of the liquidity pool | -### DOMAIN_SEPARATOR +### liquidityPool ```solidity -function DOMAIN_SEPARATOR() public view returns (bytes32) +function liquidityPool() public view returns (address liquidityPool_) ``` -Calculates the domain separator. +_Reads the stored liquidity pool address from the specified storage slot_ -_This is not cached because chainid can change on chain forks._ +#### Return Values -### permit +| Name | Type | Description | +| ---- | ---- | ----------- | +| liquidityPool_ | address | The address of the liquidity pool | + +### setLiquidityPool ```solidity -function permit(address issuer, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external +function setLiquidityPool(address newLiquidityPool) external ``` -Permit the designated spender to spend the holder's tokens - -_The permit function is used to allow a holder to designate a spender -to spend tokens on their behalf via a signed message._ +_Updates the address of the liquidity pool. Can only be called by the operator._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| issuer | address | The address of the token holder | -| spender | address | The address of the designated spender | -| value | uint256 | The number of tokens to be spent | -| deadline | uint256 | The time at which the permission to spend expires | -| v | uint8 | The recovery id of the signature | -| r | bytes32 | Half of the ECDSA signature pair | -| s | bytes32 | Half of the ECDSA signature pair | - -## StandardizedToken - -This contract implements a standardized token which extends InterchainToken functionality. -This contract also inherits Distributable and Implementation logic. +| newLiquidityPool | address | The new address of the liquidity pool | -### name +### _takeToken ```solidity -string name +function _takeToken(address from, uint256 amount) internal returns (uint256) ``` -Getter for the name of the token +_Transfers a specified amount of tokens from a specified address to the liquidity pool._ -### symbol +#### Parameters -```solidity -string symbol -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| from | address | The address to transfer tokens from | +| amount | uint256 | The amount of tokens to transfer | -Getter for the symbol of the token +#### Return Values -### decimals +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint The actual amount of tokens transferred. This allows support for fee-on-transfer tokens. | + +### _giveToken ```solidity -uint8 decimals +function _giveToken(address to, uint256 amount) internal returns (uint256) ``` -Getter for the decimals of the token - -### tokenManager_ +_Transfers a specified amount of tokens from the liquidity pool to a specified address._ -```solidity -address tokenManager_ -``` +#### Parameters -### contractId +| Name | Type | Description | +| ---- | ---- | ----------- | +| to | address | The address to transfer tokens to | +| amount | uint256 | The amount of tokens to transfer | -```solidity -function contractId() external pure returns (bytes32) -``` +#### Return Values -Getter for the contract id. +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint The actual amount of tokens transferred | -### tokenManager +### params ```solidity -function tokenManager() public view returns (contract ITokenManager) +function params(bytes operator_, address tokenAddress_, address liquidityPoolAddress) external pure returns (bytes params_) ``` -Returns the token manager for this token +Getter function for the parameters of a liquidity pool TokenManager. Mainly to be used by frontends. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | bytes | the operator of the TokenManager. | +| tokenAddress_ | address | the token to be managed. | +| liquidityPoolAddress | address | the liquidity pool to be used to store the bridged tokens. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | contract ITokenManager | ITokenManager The token manager contract | +| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | -### setup +## TokenManagerLockUnlock + +This contract is an implementation of TokenManager that locks and unlocks a specific token on behalf of the interchain token service. + +_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. +It uses the Axelar SDK to safely transfer tokens._ + +### constructor ```solidity -function setup(bytes params) external +constructor(address interchainTokenService_) public ``` -Setup function to initialize contract parameters +_Constructs an instance of TokenManagerLockUnlock. Calls the constructor +of TokenManagerAddressStorage which calls the constructor of TokenManager._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| params | bytes | The setup parameters in bytes The setup params include tokenManager, distributor, tokenName, symbol, decimals, mintAmount and mintTo | +| interchainTokenService_ | address | The address of the interchain token service contract | -### mint +### implementationType ```solidity -function mint(address account, uint256 amount) external +function implementationType() external pure returns (uint256) ``` -Function to mint new tokens -Can only be called by the distributor address. +A function that should return the implementation type of the token manager. + +### _setup + +```solidity +function _setup(bytes params_) internal +``` + +_Sets up the token address._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| account | address | The address that will receive the minted tokens | -| amount | uint256 | The amount of tokens to mint | +| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address. | -### burn +### _takeToken ```solidity -function burn(address account, uint256 amount) external +function _takeToken(address from, uint256 amount) internal returns (uint256) ``` -Function to burn tokens -Can only be called by the distributor address. +_Transfers a specified amount of tokens from a specified address to this contract._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| account | address | The address that will have its tokens burnt | -| amount | uint256 | The amount of tokens to burn | +| from | address | The address to transfer tokens from | +| amount | uint256 | The amount of tokens to transfer | -## InterchainTokenDeployer +#### Return Values -This contract is used to deploy new instances of the StandardizedTokenProxy contract. +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint The actual amount of tokens transferred. This allows support for fee-on-transfer tokens. | -### implementationAddress +### _giveToken ```solidity -address implementationAddress +function _giveToken(address to, uint256 amount) internal returns (uint256) ``` -Returns the standardized token implementation address - -### constructor +_Transfers a specified amount of tokens from this contract to a specified address._ -```solidity -constructor(address implementationAddress_) public -``` +#### Parameters -Constructor for the InterchainTokenDeployer contract +| Name | Type | Description | +| ---- | ---- | ----------- | +| to | address | The address to transfer tokens to | +| amount | uint256 | The amount of tokens to transfer | -#### Parameters +#### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| implementationAddress_ | address | Address of the StandardizedToken contract | +| [0] | uint256 | uint The actual amount of tokens transferred | -### deployInterchainToken +### params ```solidity -function deployInterchainToken(bytes32 salt, address tokenManager, address distributor, string name, string symbol, uint8 decimals) external payable returns (address tokenAddress) +function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) ``` -Deploys a new instance of the StandardizedTokenProxy contract - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| salt | bytes32 | The salt used by Create3Deployer | -| tokenManager | address | Address of the token manager | -| distributor | address | Address of the distributor | -| name | string | Name of the token | -| symbol | string | Symbol of the token | -| decimals | uint8 | Decimals of the token | +Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | bytes | the operator of the TokenManager. | +| tokenAddress_ | address | the token to be managed. | #### Return Values | Name | Type | Description | | ---- | ---- | ----------- | -| tokenAddress | address | Address of the deployed token | +| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | -### deployedAddress +## TokenManagerLockUnlockFee + +This contract is an implementation of TokenManager that locks and unlocks a specific token on behalf of the interchain token service. + +_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. +It uses the Axelar SDK to safely transfer tokens._ + +### constructor ```solidity -function deployedAddress(bytes32 salt) external view returns (address tokenAddress) +constructor(address interchainTokenService_) public ``` -Returns the standardized token deployment address. +_Constructs an instance of TokenManagerLockUnlock. Calls the constructor +of TokenManagerAddressStorage which calls the constructor of TokenManager._ -#### Return Values +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| tokenAddress | address | the token address. | - -## AddressTracker +| interchainTokenService_ | address | The address of the interchain token service contract | -### constructor +### implementationType ```solidity -constructor(address owner_, string chainName_, string[] trustedChainNames, string[] trustedAddresses) public +function implementationType() external pure returns (uint256) ``` -### setTrustedAddress +A function that should return the implementation type of the token manager. + +### _setup ```solidity -function setTrustedAddress(string chain, string address_) external +function _setup(bytes params_) internal ``` -_Sets the trusted address for the specified chain_ +_Sets up the token address._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| chain | string | Chain name to be trusted | -| address_ | string | Trusted address to be added for the chain | +| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address. | -### removeTrustedAddress +### _takeToken ```solidity -function removeTrustedAddress(string chain) external +function _takeToken(address from, uint256 amount) internal returns (uint256) ``` -_Remove the trusted address of the chain._ +_Transfers a specified amount of tokens from a specified address to this contract._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| chain | string | Chain name that should be made untrusted | - -## InterchainTokenExecutable +| from | address | The address to transfer tokens from | +| amount | uint256 | The amount of tokens to transfer | -### NotService +#### Return Values -```solidity -error NotService(address caller) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint The actual amount of tokens transferred. This allows support for fee-on-transfer tokens. | -### interchainTokenService +### _giveToken ```solidity -address interchainTokenService +function _giveToken(address to, uint256 amount) internal returns (uint256) ``` -### EXECUTE_SUCCESS - -```solidity -bytes32 EXECUTE_SUCCESS -``` +_Transfers a specified amount of tokens from this contract to a specified address._ -### constructor +#### Parameters -```solidity -constructor(address interchainTokenService_) internal -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| to | address | The address to transfer tokens to | +| amount | uint256 | The amount of tokens to transfer | -### onlyService +#### Return Values -```solidity -modifier onlyService() -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint The actual amount of tokens transferred | -### executeWithInterchainToken +### params ```solidity -function executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external virtual returns (bytes32) +function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) ``` -This will be called after the tokens arrive to this contract - -_Executable should revert unless the msg.sender is the InterchainTokenService_ +Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| sourceChain | string | the name of the source chain | -| sourceAddress | bytes | the address that sent the contract call | -| data | bytes | the data to be processed | -| tokenId | bytes32 | the tokenId of the token manager managing the token. | -| token | address | the address of the token. | -| amount | uint256 | the amount of token that was sent | +| operator_ | bytes | the operator of the TokenManager. | +| tokenAddress_ | address | the token to be managed. | -### _executeWithInterchainToken +#### Return Values -```solidity -function _executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) internal virtual -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | -## InterchainTokenExpressExecutable +## TokenManagerMintBurn -### EXPRESS_EXECUTE_SUCCESS +This contract is an implementation of TokenManager that mints and burns a specific token on behalf of the interchain token service. -```solidity -bytes32 EXPRESS_EXECUTE_SUCCESS -``` +_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. +It uses the Axelar SDK to safely transfer tokens._ ### constructor ```solidity -constructor(address interchainTokenService_) internal -``` - -### expressExecuteWithInterchainToken - -```solidity -function expressExecuteWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) external virtual returns (bytes32) +constructor(address interchainTokenService_) public ``` -This will be called after the tokens arrive to this contract - -_Executable should revert unless the msg.sender is the InterchainTokenService_ +_Constructs an instance of TokenManagerMintBurn. Calls the constructor +of TokenManagerAddressStorage which calls the constructor of TokenManager._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| sourceChain | string | the name of the source chain | -| sourceAddress | bytes | the address that sent the contract call | -| data | bytes | the data to be processed | -| tokenId | bytes32 | the token id of the token manager managing the token. | -| token | address | the address of the token. | -| amount | uint256 | the amount of token that was sent | +| interchainTokenService_ | address | The address of the interchain token service contract | -## IAddressTracker +### implementationType -### setTrustedAddress +```solidity +function implementationType() external pure virtual returns (uint256) +``` + +A function that should return the implementation type of the token manager. + +### _setup ```solidity -function setTrustedAddress(string chain, string address_) external +function _setup(bytes params_) internal ``` -_Sets the trusted address for the specified chain_ +_Sets up the token address._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| chain | string | Chain name to be trusted | -| address_ | string | Trusted address to be added for the chain | +| params_ | bytes | The setup parameters in bytes. Should be encoded with the token address. | -### removeTrustedAddress +### _takeToken ```solidity -function removeTrustedAddress(string chain) external +function _takeToken(address from, uint256 amount) internal virtual returns (uint256) ``` -_Remove the trusted address of the chain._ +_Burns the specified amount of tokens from a particular address._ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| chain | string | Chain name that should be made untrusted | +| from | address | Address to burn tokens from | +| amount | uint256 | Amount of tokens to burn | -## IMockAxelarGateway +#### Return Values -This interface is used for testing with an AxelarGateway that will arbitrarily approve calls. +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint Amount of tokens burned | -### NotSelf +### _giveToken ```solidity -error NotSelf() +function _giveToken(address to, uint256 amount) internal returns (uint256) ``` -### NotProxy - -```solidity -error NotProxy() -``` +_Mints the specified amount of tokens to a particular address_ -### InvalidCodeHash +#### Parameters -```solidity -error InvalidCodeHash() -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| to | address | Address to mint tokens to | +| amount | uint256 | Amount of tokens to mint | -### SetupFailed +#### Return Values -```solidity -error SetupFailed() -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint Amount of tokens minted | -### InvalidAuthModule +### params ```solidity -error InvalidAuthModule() +function params(bytes operator_, address tokenAddress_) external pure returns (bytes params_) ``` -### InvalidTokenDeployer +Getter function for the parameters of a lock/unlock TokenManager. Mainly to be used by frontends. -```solidity -error InvalidTokenDeployer() -``` +#### Parameters -### InvalidAmount +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | bytes | the operator of the TokenManager. | +| tokenAddress_ | address | the token to be managed. | -```solidity -error InvalidAmount() -``` +#### Return Values -### InvalidChainId +| Name | Type | Description | +| ---- | ---- | ----------- | +| params_ | bytes | the resulting params to be passed to custom TokenManager deployments. | -```solidity -error InvalidChainId() -``` +## TokenManagerMintBurnFrom -### InvalidCommands +This contract is an implementation of TokenManager that mints and burns a specific token on behalf of the interchain token service. -```solidity -error InvalidCommands() -``` +_This contract extends TokenManagerAddressStorage and provides implementation for its abstract methods. +It uses the Axelar SDK to safely transfer tokens._ -### TokenDoesNotExist +### constructor ```solidity -error TokenDoesNotExist(string symbol) +constructor(address interchainTokenService_) public ``` -### TokenAlreadyExists - -```solidity -error TokenAlreadyExists(string symbol) -``` +_Constructs an instance of TokenManagerMintBurn. Calls the constructor +of TokenManagerAddressStorage which calls the constructor of TokenManager._ -### TokenDeployFailed +#### Parameters -```solidity -error TokenDeployFailed(string symbol) -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| interchainTokenService_ | address | The address of the interchain token service contract | -### TokenContractDoesNotExist +### implementationType ```solidity -error TokenContractDoesNotExist(address token) +function implementationType() external pure returns (uint256) ``` -### BurnFailed +A function that should return the implementation type of the token manager. + +### _takeToken ```solidity -error BurnFailed(string symbol) +function _takeToken(address from, uint256 amount) internal returns (uint256) ``` -### MintFailed +_Burns the specified amount of tokens from a particular address._ -```solidity -error MintFailed(string symbol) -``` +#### Parameters -### InvalidSetMintLimitsParams +| Name | Type | Description | +| ---- | ---- | ----------- | +| from | address | Address to burn tokens from | +| amount | uint256 | Amount of tokens to burn | -```solidity -error InvalidSetMintLimitsParams() -``` +#### Return Values -### ExceedMintLimit +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint256 | uint Amount of tokens burned | -```solidity -error ExceedMintLimit(string symbol) -``` +## TokenRegistrar -### TokenSent +### NotApproved ```solidity -event TokenSent(address sender, string destinationChain, string destinationAddress, string symbol, uint256 amount) +error NotApproved(address tokenAddress) ``` -### ContractCall +### service ```solidity -event ContractCall(address sender, string destinationChain, string destinationContractAddress, bytes32 payloadHash, bytes payload) +contract IInterchainTokenService service ``` -### ContractCallWithToken +### chainNameHash ```solidity -event ContractCallWithToken(address sender, string destinationChain, string destinationContractAddress, bytes32 payloadHash, bytes payload, string symbol, uint256 amount) +bytes32 chainNameHash ``` -### Executed +### PREFIX_CANONICAL_TOKEN_SALT ```solidity -event Executed(bytes32 commandId) +bytes32 PREFIX_CANONICAL_TOKEN_SALT ``` -### TokenDeployed +### PREFIX_STANDARDIZED_TOKEN_SALT ```solidity -event TokenDeployed(string symbol, address tokenAddresses) +bytes32 PREFIX_STANDARDIZED_TOKEN_SALT ``` -### ContractCallApproved +### constructor ```solidity -event ContractCallApproved(bytes32 commandId, string sourceChain, string sourceAddress, address contractAddress, bytes32 payloadHash, bytes32 sourceTxHash, uint256 sourceEventIndex) +constructor(address interchainTokenServiceAddress) public ``` -### ContractCallApprovedWithMint +### contractId ```solidity -event ContractCallApprovedWithMint(bytes32 commandId, string sourceChain, string sourceAddress, address contractAddress, bytes32 payloadHash, string symbol, uint256 amount, bytes32 sourceTxHash, uint256 sourceEventIndex) +function contractId() external pure returns (bytes32) ``` -### TokenMintLimitUpdated +Getter for the contract id. + +### standardizedTokenSalt ```solidity -event TokenMintLimitUpdated(string symbol, uint256 limit) +function standardizedTokenSalt(bytes32 chainNameHash_, address deployer, bytes32 salt) public pure returns (bytes32) ``` -### OperatorshipTransferred +### standardizedTokenId ```solidity -event OperatorshipTransferred(bytes newOperatorsData) +function standardizedTokenId(address deployer, bytes32 salt) public view returns (bytes32 tokenId) ``` -### Upgraded +### interchainTokenAddress ```solidity -event Upgraded(address implementation) +function interchainTokenAddress(address deployer, bytes32 salt) public view returns (address tokenAddress) ``` -### callContract +### deployInterchainToken ```solidity -function callContract(string destinationChain, string contractAddress, bytes payload) external +function deployInterchainToken(bytes32 salt, string name, string symbol, uint8 decimals, uint256 mintAmount, address distributor, address operator) external payable ``` -### isContractCallApproved +### deployRemoteInterchainToken ```solidity -function isContractCallApproved(bytes32 commandId, string sourceChain, string sourceAddress, address contractAddress, bytes32 payloadHash) external view returns (bool) +function deployRemoteInterchainToken(string originalChainName, bytes32 salt, address additionalDistributor, address optionalOperator, string destinationChain, uint256 gasValue) external payable ``` -### validateContractCall +### _deployInterchainToken ```solidity -function validateContractCall(bytes32 commandId, string sourceChain, string sourceAddress, bytes32 payloadHash) external returns (bool) +function _deployInterchainToken(bytes32 salt, string destinationChain, string tokenName, string tokenSymbol, uint8 tokenDecimals, bytes distributor, bytes operator, uint256 gasValue) internal ``` -### setTokenAddress +### canonicalTokenSalt ```solidity -function setTokenAddress(string symbol, address tokenAddress) external +function canonicalTokenSalt(bytes32 chainNameHash_, address tokenAddress) public pure returns (bytes32 salt) ``` -### approveContractCall +### canonicalTokenId ```solidity -function approveContractCall(bytes params, bytes32 commandId) external +function canonicalTokenId(address tokenAddress) public view returns (bytes32 tokenId) ``` -### isCommandExecuted +### registerCanonicalToken ```solidity -function isCommandExecuted(bytes32 commandId) external view returns (bool) +function registerCanonicalToken(address tokenAddress) external payable returns (bytes32 tokenId) ``` -### tokenAddresses +### deployRemoteCanonicalToken ```solidity -function tokenAddresses(string symbol) external view returns (address tokenAddress) +function deployRemoteCanonicalToken(string originalChain, address originalTokenAddress, string destinationChain, uint256 gasValue) external payable ``` -## IStandardizedTokenProxy - -_Proxy contract for StandardizedToken contracts. Inherits from FixedProxy and implements IStandardizedTokenProxy._ - -## CanonicalTokenRegistrarProxy - -_Proxy contract for interchain token service contracts. Inherits from the Proxy contract._ - -### constructor +### interchainTransfer ```solidity -constructor(address implementationAddress, address owner) public +function interchainTransfer(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable ``` -_Constructs the InterchainTokenServiceProxy contract._ - -#### Parameters - -| Name | Type | Description | -| ---- | ---- | ----------- | -| implementationAddress | address | Address of the interchain token service implementation | -| owner | address | Address of the owner of the proxy | - -### contractId +### interchainTransferFrom ```solidity -function contractId() internal pure returns (bytes32) +function interchainTransferFrom(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 amount, uint256 gasValue) external payable ``` -_Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract._ - -#### Return Values - -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | bytes32 | bytes32 identifier for this contract | - -## InterchainTokenServiceProxy +## Distributable -_Proxy contract for interchain token service contracts. Inherits from the FinalProxy contract._ +_A contract module which provides a basic access control mechanism, where +there is an account (a distributor) that can be granted exclusive access to +specific functions. This module is used through inheritance._ -### constructor +### _addDistributor ```solidity -constructor(address implementationAddress, address owner, address operator) public +function _addDistributor(address distributor_) internal ``` -_Constructs the InterchainTokenServiceProxy contract._ +_Internal function that stores the new distributor address in the correct storage slot_ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| implementationAddress | address | Address of the interchain token service implementation | -| owner | address | Address of the owner of the proxy | -| operator | address | | +| distributor_ | address | The address of the new distributor | -### contractId +### transferDistributorship ```solidity -function contractId() internal pure returns (bytes32) +function transferDistributorship(address distributor_) external ``` -_Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract._ - -#### Return Values - -| Name | Type | Description | -| ---- | ---- | ----------- | -| [0] | bytes32 | bytes32 identifier for this contract | - -## TokenRegistrarProxy - -_Proxy contract for interchain token service contracts. Inherits from the Proxy contract._ - -### constructor - -```solidity -constructor(address implementationAddress, address owner) public -``` +Change the distributor of the contract -_Constructs the InterchainTokenServiceProxy contract._ +_Can only be called by the current distributor_ #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| implementationAddress | address | Address of the interchain token service implementation | -| owner | address | Address of the owner of the proxy | +| distributor_ | address | The address of the new distributor | -### contractId +### proposeDistributorship ```solidity -function contractId() internal pure returns (bytes32) +function proposeDistributorship(address distributor_) external ``` -_Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract._ +Proposed a change of the distributor of the contract -#### Return Values +_Can only be called by the current distributor_ + +#### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| [0] | bytes32 | bytes32 identifier for this contract | - -## InterchainExecutableTest - -### MessageReceived - -```solidity -event MessageReceived(string sourceChain, bytes sourceAddress, address receiver, string message, bytes32 tokenId, uint256 amount) -``` - -### constructor - -```solidity -constructor(address interchainTokenService_) public -``` - -### lastMessage - -```solidity -string lastMessage -``` - -### _executeWithInterchainToken - -```solidity -function _executeWithInterchainToken(string sourceChain, bytes sourceAddress, bytes data, bytes32 tokenId, address token, uint256 amount) internal -``` - -## DistributableTest - -### nonce - -```solidity -uint256 nonce -``` - -### constructor - -```solidity -constructor(address distributor) public -``` +| distributor_ | address | The address of the new distributor | -### testDistributable +### acceptDistributorship ```solidity -function testDistributable() external +function acceptDistributorship(address fromDistributor) external ``` -### distributorRole - -```solidity -function distributorRole() external pure returns (uint8) -``` +Accept a change of the distributor of the contract -## FlowLimitTest +_Can only be called by the proposed distributor_ -### TOKEN_ID +### isDistributor ```solidity -bytes32 TOKEN_ID +function isDistributor(address addr) external view returns (bool) ``` -### setFlowLimit - -```solidity -function setFlowLimit(uint256 flowLimit) external -``` +Query if an address is a distributor -### addFlowIn +#### Parameters -```solidity -function addFlowIn(uint256 flowInAmount) external -``` +| Name | Type | Description | +| ---- | ---- | ----------- | +| addr | address | the address to query for | -### addFlowOut +## FlowLimit -```solidity -function addFlowOut(uint256 flowOutAmount) external -``` +Implements flow limit logic for interchain token transfers. -## FlowLimitTestLiveNetwork +_This contract implements low-level assembly for optimization purposes._ ### FLOW_LIMIT_SLOT @@ -5202,12 +5021,6 @@ uint256 PREFIX_FLOW_OUT_AMOUNT uint256 PREFIX_FLOW_IN_AMOUNT ``` -### TOKEN_ID - -```solidity -bytes32 TOKEN_ID -``` - ### EPOCH_TIME ```solidity @@ -5231,21 +5044,58 @@ Returns the current flow limit ### _setFlowLimit ```solidity -function _setFlowLimit(uint256 flowLimit_) internal +function _setFlowLimit(uint256 flowLimit_, bytes32 tokenId) internal ``` +_Internal function to set the flow limit_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowLimit_ | uint256 | The value to set the flow limit to | +| tokenId | bytes32 | | + ### _getFlowOutSlot ```solidity function _getFlowOutSlot(uint256 epoch) internal pure returns (uint256 slot) ``` +_Returns the slot which is used to get the flow out amount for a specific epoch_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| epoch | uint256 | The epoch to get the flow out amount for | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| slot | uint256 | The slot to get the flow out amount from | + ### _getFlowInSlot ```solidity function _getFlowInSlot(uint256 epoch) internal pure returns (uint256 slot) ``` +_Returns the slot which is used to get the flow in amount for a specific epoch_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| epoch | uint256 | The epoch to get the flow in amount for | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| slot | uint256 | The slot to get the flow in amount from | + ### flowOutAmount ```solidity @@ -5280,109 +5130,244 @@ Returns the current flow in amount function _addFlow(uint256 flowLimit_, uint256 slotToAdd, uint256 slotToCompare, uint256 flowAmount) internal ``` +_Adds a flow amount while ensuring it does not exceed the flow limit_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowLimit_ | uint256 | The current flow limit value | +| slotToAdd | uint256 | The slot to add the flow to | +| slotToCompare | uint256 | The slot to compare the flow against | +| flowAmount | uint256 | The flow amount to add | + ### _addFlowOut ```solidity function _addFlowOut(uint256 flowOutAmount_) internal ``` +_Adds a flow out amount_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowOutAmount_ | uint256 | The flow out amount to add | + ### _addFlowIn ```solidity function _addFlowIn(uint256 flowInAmount_) internal ``` -### setFlowLimit +_Adds a flow in amount_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| flowInAmount_ | uint256 | The flow in amount to add | + +## Implementation + +This contract serves as a base for other contracts and enforces a proxy-first access restriction. + +_Derived contracts must implement the setup function._ + +### constructor ```solidity -function setFlowLimit(uint256 flowLimit_) external +constructor() internal ``` -### addFlowIn +_Contract constructor that sets the implementation address to the address of this contract._ + +### onlyProxy ```solidity -function addFlowIn(uint256 flowInAmount_) external +modifier onlyProxy() ``` -### addFlowOut +_Modifier to require the caller to be the proxy contract. +Reverts if the caller is the current contract (i.e., the implementation contract itself)._ + +## InterchainTokenDeployer + +This contract is used to deploy new instances of the StandardizedTokenProxy contract. + +### implementationAddress ```solidity -function addFlowOut(uint256 flowOutAmount_) external +address implementationAddress ``` -## ImplementationTest +Returns the standardized token implementation address -### val +### constructor ```solidity -uint256 val +constructor(address implementationAddress_) public ``` -### setup +Constructor for the InterchainTokenDeployer contract + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| implementationAddress_ | address | Address of the StandardizedToken contract | + +### deployInterchainToken ```solidity -function setup(bytes params) external +function deployInterchainToken(bytes32 salt, address tokenManager, address distributor, string name, string symbol, uint8 decimals) external payable returns (address tokenAddress) ``` -Called by the proxy to setup itself. - -_This should be hidden by the proxy._ +Deploys a new instance of the StandardizedTokenProxy contract #### Parameters | Name | Type | Description | | ---- | ---- | ----------- | -| params | bytes | the data to be used for the initialization. | +| salt | bytes32 | The salt used by Create3Deployer | +| tokenManager | address | Address of the token manager | +| distributor | address | Address of the distributor | +| name | string | Name of the token | +| symbol | string | Symbol of the token | +| decimals | uint8 | Decimals of the token | -## NakedProxy +#### Return Values -### implementation +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress | address | Address of the deployed token | + +### deployedAddress ```solidity -address implementation +function deployedAddress(bytes32 salt) external view returns (address tokenAddress) ``` -### constructor +Returns the standardized token deployment address. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenAddress | address | the token address. | + +## Operatable + +_A contract module which provides a basic access control mechanism, where +there is an account (a operator) that can be granted exclusive access to +specific functions. This module is used through inheritance._ + +### _addOperator ```solidity -constructor(address implementation_) public +function _addOperator(address operator_) internal ``` -### fallback +_Internal function that stores the new operator address in the correct storage slot_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | address | The address of the new operator | + +### transferOperatorship ```solidity -fallback() external payable virtual +function transferOperatorship(address operator_) external ``` -### receive +Change the operator of the contract + +_Can only be called by the current operator_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | address | The address of the new operator | + +### proposeOperatorship ```solidity -receive() external payable virtual +function proposeOperatorship(address operator_) external ``` -## OperatorableTest +Proposed a change of the operator of the contract -### nonce +_Can only be called by the current operator_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| operator_ | address | The address of the new operator | + +### acceptOperatorship ```solidity -uint256 nonce +function acceptOperatorship(address fromOperator) external ``` -### constructor +Accept a change of the operator of the contract + +_Can only be called by the proposed operator_ + +### isOperator ```solidity -constructor(address operator) public +function isOperator(address addr) external view returns (bool) ``` -### testOperatorable +Query if an address is an operator + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| addr | address | the address to query for | + +## RolesConstants + +### Roles ```solidity -function testOperatorable() external +enum Roles { + DISTRIBUTOR, + OPERATOR, + FLOW_LIMITER +} ``` -### operatorRole +## TokenManagerDeployer + +This contract is used to deploy new instances of the TokenManagerProxy contract. + +### deployTokenManager ```solidity -function operatorRole() external pure returns (uint8) +function deployTokenManager(bytes32 tokenId, uint256 implementationType, bytes params) external payable returns (address tokenManager) ``` +Deploys a new instance of the TokenManagerProxy contract + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenId | bytes32 | The unique identifier for the token | +| implementationType | uint256 | Token manager implementation type | +| params | bytes | Additional parameters used in the setup of the token manager | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenManager | address | The address of the deployed tokenManager | + diff --git a/test/TokenRegistrars.js b/test/TokenRegistrars.js index adfd49a7..e63c43e8 100644 --- a/test/TokenRegistrars.js +++ b/test/TokenRegistrars.js @@ -17,9 +17,9 @@ const IStandardizedToken = require('../artifacts/contracts/interfaces/IStandardi const { deployAll, deployContract } = require('../scripts/deploy'); const { getRandomBytes32 } = require('./utils'); -// const SELECTOR_SEND_TOKEN_WITH_DATA = 2; -// const SELECTOR_DEPLOY_TOKEN_MANAGER = 3; -const SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN = 4; +// const MESSAGE_TYPE_SEND_TOKEN_WITH_DATA = 2; +// const MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER = 3; +const MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN = 4; const LOCK_UNLOCK = 2; const MINT_BURN = 0; @@ -78,7 +78,7 @@ describe('Token Registrars', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', '0x'], + [MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', '0x'], ); await expect(tokenRegistrar.registerCanonicalToken(token.address)) @@ -88,8 +88,8 @@ describe('Token Registrars', () => { await expect( tokenRegistrar.deployRemoteCanonicalToken(chainName, token.address, destinationChain, gasValue, { value: gasValue }), ) - .to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs(tokenId, name, symbol, decimals, '0x', '0x', destinationChain, gasValue) + .to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, name, symbol, decimals, '0x', '0x', destinationChain) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, keccak256(payload), gasValue, wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -113,7 +113,7 @@ describe('Token Registrars', () => { // await expect( // tokenRegistrar.interchainTransferFrom(tokenId, '', arrayify(wallet.address), amount, 0), // ) - // // .to.emit(service, 'TokenSent') + // // .to.emit(service, 'InterchainTransfer') // // .withArgs(tokenId, destinationChain, destinationAddress, amount) // .to.emit(token, 'Transfer') // .withArgs(wallet.address, tokenRegistrar.address, amount) @@ -185,7 +185,7 @@ describe('Token Registrars', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], [ - SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, + MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, @@ -200,17 +200,8 @@ describe('Token Registrars', () => { value: gasValue, }), ) - .to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs( - tokenId, - name, - symbol, - decimals, - wallet.address.toLowerCase(), - wallet.address.toLowerCase(), - destinationChain, - gasValue, - ) + .to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, name, symbol, decimals, wallet.address.toLowerCase(), wallet.address.toLowerCase(), destinationChain) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, keccak256(payload), gasValue, wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -242,7 +233,7 @@ describe('Token Registrars', () => { params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', wallet.address], + [MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', wallet.address], ); await expect( @@ -250,8 +241,8 @@ describe('Token Registrars', () => { value: gasValue, }), ) - .to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs(tokenId, name, symbol, decimals, '0x', wallet.address.toLowerCase(), destinationChain, gasValue) + .to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, name, symbol, decimals, '0x', wallet.address.toLowerCase(), destinationChain) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, keccak256(payload), gasValue, wallet.address) .and.to.emit(gateway, 'ContractCall') diff --git a/test/TokenService.js b/test/TokenService.js index 6448caf2..c7d8e77b 100644 --- a/test/TokenService.js +++ b/test/TokenService.js @@ -23,11 +23,11 @@ const { deployTokenManagerImplementations, } = require('../scripts/deploy'); -const SELECTOR_RECEIVE_TOKEN = 1; -const SELECTOR_RECEIVE_TOKEN_WITH_DATA = 2; -const SELECTOR_DEPLOY_TOKEN_MANAGER = 3; -const SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN = 4; -const INVALID_SELECTOR = 5; +const MESSAGE_TYPE_INTERCHAIN_TRANSFER = 1; +const MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA = 2; +const MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER = 3; +const MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN = 4; +const INVALID_MESSAGE_TYPE = 5; const MINT_BURN = 0; const MINT_BURN_FROM = 1; @@ -382,7 +382,7 @@ describe('Interchain Token Service', () => { let txPaused; beforeEach(async () => { - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -411,7 +411,7 @@ describe('Interchain Token Service', () => { it('Should revert when registering a standardized token when service is paused', async () => { const salt = getRandomBytes32(); - txPaused = await service.setPaused(true); + txPaused = await service.setPauseStatus(true); await txPaused.wait(); await expectRevert( @@ -431,7 +431,7 @@ describe('Interchain Token Service', () => { 'Pause', ); - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -483,7 +483,7 @@ describe('Interchain Token Service', () => { let txPaused; beforeEach(async () => { - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -501,7 +501,15 @@ describe('Interchain Token Service', () => { const tokenId = await service.interchainTokenId(wallet.address, salt); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, tokenName, tokenSymbol, tokenDecimals, distributor, operator], + [ + MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, + tokenId, + tokenName, + tokenSymbol, + tokenDecimals, + distributor, + operator, + ], ); await expect( service.deployInterchainToken( @@ -518,8 +526,8 @@ describe('Interchain Token Service', () => { }, ), ) - .to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs(tokenId, tokenName, tokenSymbol, tokenDecimals, distributor, operator, destinationChain, gasValue) + .to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, tokenName, tokenSymbol, tokenDecimals, distributor, operator, destinationChain) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, keccak256(payload), gasValue, wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -527,7 +535,7 @@ describe('Interchain Token Service', () => { }); it('Should revert on remote standardized token deployment if paused', async () => { - let tx = await service.setPaused(true); + let tx = await service.setPauseStatus(true); await tx.wait(); await expectRevert( @@ -550,7 +558,7 @@ describe('Interchain Token Service', () => { 'Pause', ); - tx = await service.setPaused(false); + tx = await service.setPauseStatus(false); await tx.wait(); }); }); @@ -567,7 +575,7 @@ describe('Interchain Token Service', () => { }); beforeEach(async () => { - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -578,7 +586,15 @@ describe('Interchain Token Service', () => { const commandId = getRandomBytes32(); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, tokenName, tokenSymbol, tokenDecimals, distributor, operator], + [ + MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, + tokenId, + tokenName, + tokenSymbol, + tokenDecimals, + distributor, + operator, + ], ); await expectRevert( @@ -598,7 +614,15 @@ describe('Interchain Token Service', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], [operator, tokenAddress]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, tokenName, tokenSymbol, tokenDecimals, distributor, operator], + [ + MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, + tokenId, + tokenName, + tokenSymbol, + tokenDecimals, + distributor, + operator, + ], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -621,7 +645,15 @@ describe('Interchain Token Service', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], [operator, tokenAddress]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, tokenName, tokenSymbol, tokenDecimals, distributor, operator], + [ + MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, + tokenId, + tokenName, + tokenSymbol, + tokenDecimals, + distributor, + operator, + ], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -644,7 +676,15 @@ describe('Interchain Token Service', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', tokenAddress]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, tokenName, tokenSymbol, tokenDecimals, distributor, operator], + [ + MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, + tokenId, + tokenName, + tokenSymbol, + tokenDecimals, + distributor, + operator, + ], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -676,7 +716,7 @@ describe('Interchain Token Service', () => { let txPaused; beforeEach(async () => { - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -805,7 +845,7 @@ describe('Interchain Token Service', () => { }); it('Should revert when deploying a custom token manager if paused', async () => { - let tx2 = await service.setPaused(true); + let tx2 = await service.setPauseStatus(true); await tx2.wait(); const tokenName = 'Token Name'; @@ -819,7 +859,7 @@ describe('Interchain Token Service', () => { await expectRevert((gasOptions) => service.deployTokenManager(salt, '', LOCK_UNLOCK, params, 0, gasOptions), service, 'Pause'); - tx2 = await service.setPaused(false); + tx2 = await service.setPauseStatus(false); await tx2.wait(); }); }); @@ -828,7 +868,7 @@ describe('Interchain Token Service', () => { let txPaused; beforeEach(async () => { - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -851,12 +891,12 @@ describe('Interchain Token Service', () => { const type = LOCK_UNLOCK; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'uint256', 'bytes'], - [SELECTOR_DEPLOY_TOKEN_MANAGER, tokenId, type, params], + [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, type, params], ); await expect(service.deployTokenManager(salt, destinationChain, type, params, gasValue, { value: gasValue })) - .to.emit(service, 'RemoteTokenManagerDeploymentInitialized') - .withArgs(tokenId, destinationChain, gasValue, type, params) + .to.emit(service, 'TokenManagerDeploymentStarted') + .withArgs(tokenId, destinationChain, type, params) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, keccak256(payload), gasValue, wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -876,7 +916,7 @@ describe('Interchain Token Service', () => { }); it('Should revert on remote custom token manager deployment if paused', async () => { - let tx = await service.setPaused(true); + let tx = await service.setPauseStatus(true); await tx.wait(); const salt = getRandomBytes32(); @@ -893,7 +933,7 @@ describe('Interchain Token Service', () => { service, 'Pause', ); - tx = await service.setPaused(false); + tx = await service.setPauseStatus(false); await tx.wait(); }); }); @@ -902,7 +942,7 @@ describe('Interchain Token Service', () => { let txPaused; beforeEach(async () => { - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -925,12 +965,12 @@ describe('Interchain Token Service', () => { const type = LOCK_UNLOCK; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'uint256', 'bytes'], - [SELECTOR_DEPLOY_TOKEN_MANAGER, tokenId, type, params], + [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, type, params], ); await expect(service.deployTokenManager(salt, destinationChain, type, params, gasValue, { value: gasValue })) - .to.emit(service, 'RemoteTokenManagerDeploymentInitialized') - .withArgs(tokenId, destinationChain, gasValue, type, params) + .to.emit(service, 'TokenManagerDeploymentStarted') + .withArgs(tokenId, destinationChain, type, params) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, keccak256(payload), gasValue, wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -950,7 +990,7 @@ describe('Interchain Token Service', () => { }); it('Should revert on remote custom token manager deployment if paused', async () => { - let tx = await service.setPaused(true); + let tx = await service.setPauseStatus(true); await tx.wait(); const salt = getRandomBytes32(); @@ -967,7 +1007,7 @@ describe('Interchain Token Service', () => { service, 'Pause', ); - tx = await service.setPaused(false); + tx = await service.setPauseStatus(false); await tx.wait(); }); }); @@ -990,7 +1030,7 @@ describe('Interchain Token Service', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, token.address]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'uint256', 'bytes'], - [SELECTOR_DEPLOY_TOKEN_MANAGER, tokenId, LOCK_UNLOCK, params], + [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, LOCK_UNLOCK, params], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -1014,7 +1054,7 @@ describe('Interchain Token Service', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, token.address]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'uint256', 'bytes'], - [SELECTOR_DEPLOY_TOKEN_MANAGER, tokenId, MINT_BURN, params], + [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, MINT_BURN, params], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -1039,7 +1079,7 @@ describe('Interchain Token Service', () => { const sendAmount = type === 'lockUnlockFee' ? amount - 10 : amount; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, sendAmount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, sendAmount], ); const payloadHash = keccak256(payload); @@ -1056,7 +1096,7 @@ describe('Interchain Token Service', () => { .withArgs(service.address, destinationChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, gasValue, wallet.address) - .to.emit(service, 'TokenSent') + .to.emit(service, 'InterchainTransfer') .withArgs(tokenId, destinationChain, destAddress, sendAmount); }); } @@ -1064,7 +1104,7 @@ describe('Interchain Token Service', () => { it(`Should revert on initiate interchain token transfer when service is paused`, async () => { const [, tokenManager] = await deployFunctions.lockUnlock(`Test Token lockUnlock`, 'TT', 12, amount); - let txPaused = await service.setPaused(true); + let txPaused = await service.setPauseStatus(true); await txPaused.wait(); await expectRevert( @@ -1074,7 +1114,7 @@ describe('Interchain Token Service', () => { 'Pause', ); - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); @@ -1083,7 +1123,7 @@ describe('Interchain Token Service', () => { await expectRevert( (gasOptions) => - service.transmitSendToken(tokenId, tokenManager.address, destinationChain, destAddress, amount, '0x', { + service.transmitInterchainTransfer(tokenId, tokenManager.address, destinationChain, destAddress, amount, '0x', { ...gasOptions, value: gasValue, }), @@ -1111,7 +1151,7 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, wallet.address, service.address, payload); @@ -1128,11 +1168,11 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); - let txPaused = await service.setPaused(true); + let txPaused = await service.setPauseStatus(true); await txPaused.wait(); await expectRevert( @@ -1141,25 +1181,25 @@ describe('Interchain Token Service', () => { 'Pause', ); - txPaused = await service.setPaused(false); + txPaused = await service.setPauseStatus(false); await txPaused.wait(); }); - it('Should revert on execute with invalid selector', async () => { + it('Should revert on execute with invalid messageType', async () => { const [token, tokenManager, tokenId] = await deployFunctions.lockUnlock(`Test Token Lock Unlock`, 'TT', 12, amount); (await await token.transfer(tokenManager.address, amount)).wait(); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'uint256'], - [INVALID_SELECTOR, tokenId, destAddress, amount], + [INVALID_MESSAGE_TYPE, tokenId, destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); await expectRevert( (gasOptions) => service.execute(commandId, sourceChain, sourceAddress, payload, gasOptions), service, - 'SelectorUnknown', - [INVALID_SELECTOR], + 'InvalidMessageType', + [INVALID_MESSAGE_TYPE], ); }); }); @@ -1180,14 +1220,14 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); await expect(service.execute(commandId, sourceChain, sourceAddress, payload)) .to.emit(token, 'Transfer') .withArgs(tokenManager.address, destAddress, amount) - .and.to.emit(service, 'TokenReceived') + .and.to.emit(service, 'InterchainTransferReceived') .withArgs(tokenId, sourceChain, hexlify(wallet.address), destAddress, amount); }); @@ -1196,14 +1236,14 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); await expect(service.execute(commandId, sourceChain, sourceAddress, payload)) .to.emit(token, 'Transfer') .withArgs(AddressZero, destAddress, amount) - .and.to.emit(service, 'TokenReceived') + .and.to.emit(service, 'InterchainTransferReceived') .withArgs(tokenId, sourceChain, hexlify(wallet.address), destAddress, amount); }); @@ -1213,14 +1253,14 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); await expect(service.execute(commandId, sourceChain, sourceAddress, payload)) .to.emit(token, 'Transfer') .withArgs(tokenManager.address, destAddress, amount) - .and.to.emit(service, 'TokenReceived') + .and.to.emit(service, 'InterchainTransferReceived') .withArgs(tokenId, sourceChain, hexlify(wallet.address), destAddress, amount - 10); }); }); @@ -1242,7 +1282,7 @@ describe('Interchain Token Service', () => { const sendAmount = type === 'lockUnlockFee' ? amount - 10 : amount; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, data], ); const payloadHash = keccak256(payload); @@ -1259,7 +1299,7 @@ describe('Interchain Token Service', () => { .withArgs(service.address, destinationChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, gasValue, wallet.address) - .to.emit(service, 'TokenSentWithData') + .to.emit(service, 'InterchainTransferWithData') .withArgs(tokenId, destinationChain, destAddress, sendAmount, sourceAddress, data); }); } @@ -1271,7 +1311,7 @@ describe('Interchain Token Service', () => { const metadata = '0x00000000'; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, '0x'], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, '0x'], ); const payloadHash = keccak256(payload); @@ -1286,18 +1326,18 @@ describe('Interchain Token Service', () => { .withArgs(wallet.address, transferToAddress, amount) .and.to.emit(gateway, 'ContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, payload) - .to.emit(service, 'TokenSentWithData') + .to.emit(service, 'InterchainTransferWithData') .withArgs(tokenId, destinationChain, destAddress, sendAmount, sourceAddress, '0x'); }); } for (const type of ['lockUnlock', 'mintBurn', 'lockUnlockFee']) { - it(`Should be able to initiate an interchain token transfer via the sendTokenWithData function on the service [${type}]`, async () => { + it(`Should be able to initiate an interchain token transfer via the callContractWithInterchainToken function on the service [${type}]`, async () => { const [token, tokenManager, tokenId] = await deployFunctions[type](`Test Token ${type}`, 'TT', 12, amount); const sendAmount = type === 'lockUnlockFee' ? amount - 10 : amount; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, data], ); const payloadHash = keccak256(payload); @@ -1307,12 +1347,12 @@ describe('Interchain Token Service', () => { transferToAddress = tokenManager.address; } - await expect(service.sendTokenWithData(tokenId, destinationChain, destAddress, amount, data)) + await expect(service.callContractWithInterchainToken(tokenId, destinationChain, destAddress, amount, data)) .and.to.emit(token, 'Transfer') .withArgs(wallet.address, transferToAddress, amount) .and.to.emit(gateway, 'ContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, payload) - .to.emit(service, 'TokenSentWithData') + .to.emit(service, 'InterchainTransferWithData') .withArgs(tokenId, destinationChain, destAddress, sendAmount, sourceAddress, data); }); } @@ -1350,7 +1390,7 @@ describe('Interchain Token Service', () => { const data = defaultAbiCoder.encode(['address', 'string'], [wallet.address, msg]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -1359,7 +1399,7 @@ describe('Interchain Token Service', () => { .withArgs(tokenManager.address, destAddress, amount) .to.emit(token, 'Transfer') .withArgs(destAddress, wallet.address, amount) - .and.to.emit(service, 'TokenReceivedWithData') + .and.to.emit(service, 'InterchainTransferReceivedWithData') .withArgs(tokenId, sourceChain, sourceAddressForService, destAddress, amount) .and.to.emit(executable, 'MessageReceived') .withArgs(sourceChain, sourceAddressForService, wallet.address, msg, tokenId, amount); @@ -1374,7 +1414,7 @@ describe('Interchain Token Service', () => { const data = defaultAbiCoder.encode(['address', 'string'], [wallet.address, msg]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -1383,7 +1423,7 @@ describe('Interchain Token Service', () => { .withArgs(AddressZero, destAddress, amount) .to.emit(token, 'Transfer') .withArgs(destAddress, wallet.address, amount) - .and.to.emit(service, 'TokenReceivedWithData') + .and.to.emit(service, 'InterchainTransferReceivedWithData') .withArgs(tokenId, sourceChain, sourceAddressForService, destAddress, amount) .and.to.emit(executable, 'MessageReceived') .withArgs(sourceChain, sourceAddressForService, wallet.address, msg, tokenId, amount); @@ -1398,7 +1438,7 @@ describe('Interchain Token Service', () => { const data = defaultAbiCoder.encode(['address', 'string'], [wallet.address, msg]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -1407,7 +1447,7 @@ describe('Interchain Token Service', () => { .withArgs(tokenManager.address, destAddress, amount) .to.emit(token, 'Transfer') .withArgs(destAddress, wallet.address, amount - 10) - .and.to.emit(service, 'TokenReceivedWithData') + .and.to.emit(service, 'InterchainTransferReceivedWithData') .withArgs(tokenId, sourceChain, sourceAddressForService, destAddress, amount - 10) .and.to.emit(executable, 'MessageReceived') .withArgs(sourceChain, sourceAddressForService, wallet.address, msg, tokenId, amount - 10); @@ -1428,7 +1468,7 @@ describe('Interchain Token Service', () => { const sendAmount = type === 'lockUnlockFee' ? amount - 10 : amount; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, sendAmount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, sendAmount], ); const payloadHash = keccak256(payload); @@ -1445,7 +1485,7 @@ describe('Interchain Token Service', () => { .withArgs(service.address, destinationChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, gasValue, wallet.address) - .to.emit(service, 'TokenSent') + .to.emit(service, 'InterchainTransfer') .withArgs(tokenId, destinationChain, destAddress, sendAmount); }); @@ -1454,7 +1494,7 @@ describe('Interchain Token Service', () => { const sendAmount = type === 'lockUnlockFee' ? amount - 10 : amount; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, sendAmount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, sendAmount], ); const payloadHash = keccak256(payload); @@ -1479,7 +1519,7 @@ describe('Interchain Token Service', () => { .withArgs(service.address, destinationChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, gasValue, spender.address) - .to.emit(service, 'TokenSent') + .to.emit(service, 'InterchainTransfer') .withArgs(tokenId, destinationChain, destAddress, sendAmount); }); } @@ -1489,7 +1529,7 @@ describe('Interchain Token Service', () => { const sendAmount = amount; const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, sendAmount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, sendAmount], ); const payloadHash = keccak256(payload); @@ -1510,7 +1550,7 @@ describe('Interchain Token Service', () => { .withArgs(service.address, destinationChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, gasValue, spender.address) - .to.emit(service, 'TokenSent') + .to.emit(service, 'InterchainTransfer') .withArgs(tokenId, destinationChain, destAddress, sendAmount); }); }); @@ -1533,7 +1573,7 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddress, destAddress, sendAmount, data], ); const payloadHash = keccak256(payload); @@ -1551,7 +1591,7 @@ describe('Interchain Token Service', () => { .withArgs(service.address, destinationChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destinationChain, service.address, payloadHash, gasValue, wallet.address) - .to.emit(service, 'TokenSentWithData') + .to.emit(service, 'InterchainTransferWithData') .withArgs(tokenId, destinationChain, destAddress, sendAmount, sourceAddress, data); }); } @@ -1581,7 +1621,7 @@ describe('Interchain Token Service', () => { it('Should express execute', async () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destinationAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destinationAddress, amount], ); await expect(service.expressExecute(commandId, sourceChain, sourceAddress, payload)) .to.emit(service, 'ExpressExecuted') @@ -1593,7 +1633,7 @@ describe('Interchain Token Service', () => { it('Should express execute with token', async () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', ' bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddress, executable.address, amount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddress, executable.address, amount, data], ); await expect(service.expressExecute(commandId, sourceChain, sourceAddress, payload)) .to.emit(service, 'ExpressExecuted') @@ -1623,7 +1663,7 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -1635,22 +1675,22 @@ describe('Interchain Token Service', () => { ); }); - it('Should revert with invalid selector', async () => { + it('Should revert with invalid messageType', async () => { const [token, tokenManager, tokenId] = await deployFunctions.lockUnlock(`Test Token Lock Unlock`, 'TT', 12, 2 * amount); await (await token.transfer(tokenManager.address, amount)).wait(); await (await token.approve(service.address, amount)).wait(); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'uint256'], - [SELECTOR_DEPLOY_TOKEN_MANAGER, tokenId, destAddress, amount], + [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, destAddress, amount], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); await expectRevert( (gasOptions) => service.expressExecute(commandId, sourceChain, sourceAddress, payload, gasOptions), service, - 'InvalidExpressSelector', - [SELECTOR_DEPLOY_TOKEN_MANAGER], + 'InvalidExpressMessageType', + [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER], ); }); @@ -1661,7 +1701,7 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = getRandomBytes32(); @@ -1682,7 +1722,7 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = getRandomBytes32(); @@ -1703,7 +1743,7 @@ describe('Interchain Token Service', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const commandId = getRandomBytes32(); @@ -1740,7 +1780,7 @@ describe('Interchain Token Service', () => { const data = defaultAbiCoder.encode(['address', 'string'], [wallet.address, msg]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], ); const commandId = getRandomBytes32(); @@ -1765,7 +1805,7 @@ describe('Interchain Token Service', () => { const data = defaultAbiCoder.encode(['address', 'string'], [wallet.address, msg]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], ); const commandId = getRandomBytes32(); @@ -1790,7 +1830,7 @@ describe('Interchain Token Service', () => { const data = defaultAbiCoder.encode(['address', 'string'], [wallet.address, msg]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_RECEIVE_TOKEN_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER_WITH_DATA, tokenId, sourceAddressForService, destAddress, amount, data], ); const commandId = await approveContractCall(gateway, sourceChain, sourceAddress, service.address, payload); @@ -1833,7 +1873,7 @@ describe('Interchain Token Service', () => { async function receiveToken(sendAmount) { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), wallet.address, sendAmount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), wallet.address, sendAmount], ); const commandId = await approveContractCall(gateway, destinationChain, service.address, service.address, payload); @@ -1862,8 +1902,6 @@ describe('Interchain Token Service', () => { const [, tokenManager, tokenId] = await deployFunctions[type](`Test Token ${type}`, 'TT', 12, mintAmount); tokenIds.push(tokenId); tokenManagers.push(tokenManager); - - await tokenManager.addFlowLimiter(service.address).then((tx) => tx.wait()); } const flowLimits = new Array(tokenManagers.length).fill(flowLimit); diff --git a/test/TokenServiceFullFlow.js b/test/TokenServiceFullFlow.js index 7ea54f1f..8129d2a7 100644 --- a/test/TokenServiceFullFlow.js +++ b/test/TokenServiceFullFlow.js @@ -1,5 +1,5 @@ 'use strict'; -/* + const chai = require('chai'); const { expect } = chai; require('dotenv').config(); @@ -15,16 +15,17 @@ const ITokenManagerMintBurn = require('../artifacts/contracts/interfaces/ITokenM const { getRandomBytes32, expectRevert } = require('./utils'); const { deployAll, deployContract } = require('../scripts/deploy'); -const SELECTOR_RECEIVE_TOKEN = 1; -const SELECTOR_DEPLOY_TOKEN_MANAGER = 3; -const SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN = 4; +const MESSAGE_TYPE_INTERCHAIN_TRANSFER = 1; +const MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER = 3; +const MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN = 4; const DISTRIBUTOR_ROLE = 0; const MINT_BURN = 0; const LOCK_UNLOCK = 2; -describe('Interchain Token Service Full Flow', () => { +// TODO: Refactor skipped tests +describe.skip('Interchain Token Service Full Flow', () => { let wallet; let service, gateway, gasService, tokenManager, tokenId; const name = 'tokenName'; @@ -67,20 +68,20 @@ describe('Interchain Token Service Full Flow', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', '0x', 0, '0x'], + [MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', '0x', 0, '0x'], ); const expectedTokenManagerAddress = await service.tokenManagerAddress(tokenId); await expect(service.multicall(data, { value })) .to.emit(service, 'TokenManagerDeployed') .withArgs(tokenId, expectedTokenManagerAddress, LOCK_UNLOCK, params) - .and.to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, '0x', otherChains[0], gasValues[0]) + .and.to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, '0x', otherChains[0]) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, otherChains[0], service.address, keccak256(payload), gasValues[0], wallet.address) .and.to.emit(gateway, 'ContractCall') .withArgs(service.address, otherChains[0], service.address, keccak256(payload), payload) - .and.to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, '0x', otherChains[1], gasValues[1]) + .and.to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, '0x', otherChains[1]) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, otherChains[1], service.address, keccak256(payload), gasValues[1], wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -95,7 +96,7 @@ describe('Interchain Token Service Full Flow', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const payloadHash = keccak256(payload); @@ -110,7 +111,7 @@ describe('Interchain Token Service Full Flow', () => { .withArgs(service.address, destChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destChain, service.address, payloadHash, gasValue, wallet.address) - .to.emit(service, 'TokenSent') + .to.emit(service, 'InterchainTransfer') .withArgs(tokenId, destChain, destAddress, amount); }); @@ -186,7 +187,7 @@ describe('Interchain Token Service Full Flow', () => { const params = defaultAbiCoder.encode(['bytes', 'address'], [wallet.address, token.address]); const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'string', 'string', 'uint8', 'bytes', 'bytes', 'uint256', 'bytes'], - [SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', '0x', 0, wallet.address], + [MESSAGE_TYPE_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN, tokenId, name, symbol, decimals, '0x', '0x', 0, wallet.address], ); const tx = service.multicall(data, { value }); @@ -197,14 +198,14 @@ describe('Interchain Token Service Full Flow', () => { .withArgs(tokenId, expectedTokenAddress, wallet.address, name, symbol, decimals, tokenCap, wallet.address) .and.to.emit(service, 'TokenManagerDeployed') .withArgs(tokenId, expectedTokenManagerAddress, MINT_BURN, params) - .and.to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, wallet.address.toLowerCase(), otherChains[0], gasValues[0]) + .and.to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, wallet.address.toLowerCase(), otherChains[0]) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, otherChains[0], service.address, keccak256(payload), gasValues[0], wallet.address) .and.to.emit(gateway, 'ContractCall') .withArgs(service.address, otherChains[0], service.address, keccak256(payload), payload) - .and.to.emit(service, 'RemoteInterchainTokenDeploymentInitialized') - .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, wallet.address.toLowerCase(), otherChains[1], gasValues[1]) + .and.to.emit(service, 'InterchainTokenDeploymentStarted') + .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, wallet.address.toLowerCase(), otherChains[1]) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, otherChains[1], service.address, keccak256(payload), gasValues[1], wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -219,7 +220,7 @@ describe('Interchain Token Service Full Flow', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const payloadHash = keccak256(payload); @@ -230,7 +231,7 @@ describe('Interchain Token Service Full Flow', () => { .withArgs(service.address, destChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destChain, service.address, payloadHash, gasValue, wallet.address) - .to.emit(service, 'TokenSent') + .to.emit(service, 'InterchainTransfer') .withArgs(tokenId, destChain, destAddress, amount); }); @@ -294,20 +295,20 @@ describe('Interchain Token Service Full Flow', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'uint256', 'bytes'], - [SELECTOR_DEPLOY_TOKEN_MANAGER, tokenId, MINT_BURN, params], + [MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, MINT_BURN, params], ); const expectedTokenManagerAddress = await service.tokenManagerAddress(tokenId); await expect(service.multicall(data, { value })) .to.emit(service, 'TokenManagerDeployed') .withArgs(tokenId, expectedTokenManagerAddress, MINT_BURN, params) - .and.to.emit(service, 'RemoteTokenManagerDeploymentInitialized') - .withArgs(tokenId, otherChains[0], gasValues[0], MINT_BURN, params) + .and.to.emit(service, 'TokenManagerDeploymentStarted') + .withArgs(tokenId, otherChains[0], MINT_BURN, params) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, otherChains[0], service.address, keccak256(payload), gasValues[0], wallet.address) .and.to.emit(gateway, 'ContractCall') .withArgs(service.address, otherChains[0], service.address, keccak256(payload), payload) - .and.to.emit(service, 'RemoteTokenManagerDeploymentInitialized') - .withArgs(tokenId, otherChains[1], gasValues[1], MINT_BURN, params) + .and.to.emit(service, 'TokenManagerDeploymentStarted') + .withArgs(tokenId, otherChains[1], MINT_BURN, params) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, otherChains[1], service.address, keccak256(payload), gasValues[1], wallet.address) .and.to.emit(gateway, 'ContractCall') @@ -347,7 +348,7 @@ describe('Interchain Token Service Full Flow', () => { const payload = defaultAbiCoder.encode( ['uint256', 'bytes32', 'bytes', 'bytes', 'uint256'], - [SELECTOR_RECEIVE_TOKEN, tokenId, hexlify(wallet.address), destAddress, amount], + [MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, hexlify(wallet.address), destAddress, amount], ); const payloadHash = keccak256(payload); @@ -358,9 +359,8 @@ describe('Interchain Token Service Full Flow', () => { .withArgs(service.address, destChain, service.address, payloadHash, payload) .and.to.emit(gasService, 'NativeGasPaidForContractCall') .withArgs(service.address, destChain, service.address, payloadHash, gasValue, wallet.address) - .to.emit(service, 'TokenSent') + .to.emit(service, 'InterchainTransfer') .withArgs(tokenId, destChain, destAddress, amount); }); }); }); -*/