diff --git a/.solhint.json b/.solhint.json index 8007bba1..e2992d2b 100644 --- a/.solhint.json +++ b/.solhint.json @@ -8,6 +8,7 @@ "no-inline-assembly": "off", "no-empty-blocks": "off", "avoid-low-level-calls": "off", - "not-rely-on-time": "off" + "not-rely-on-time": "off", + "immutable-vars-naming": "off" } } diff --git a/contracts/interchain-token-service/InterchainTokenService.sol b/contracts/interchain-token-service/InterchainTokenService.sol index 3f5e1582..23ca2420 100644 --- a/contracts/interchain-token-service/InterchainTokenService.sol +++ b/contracts/interchain-token-service/InterchainTokenService.sol @@ -18,7 +18,6 @@ import { IRemoteAddressValidator } from '../interfaces/IRemoteAddressValidator.s import { IInterchainTokenExecutable } from '../interfaces/IInterchainTokenExecutable.sol'; import { IInterchainTokenExpressExecutable } from '../interfaces/IInterchainTokenExpressExecutable.sol'; import { ITokenManager } from '../interfaces/ITokenManager.sol'; -import { ITokenManagerProxy } from '../interfaces/ITokenManagerProxy.sol'; import { IERC20Named } from '../interfaces/IERC20Named.sol'; import { AddressBytesUtils } from '../libraries/AddressBytesUtils.sol'; @@ -475,13 +474,21 @@ contract InterchainTokenService is } } + /** + * @notice Transfer a token interchain. + * @param tokenId the tokenId for the token link. + * @param destinationChain the name of the chain to send the token to. + * @param destinationAddress the recipient of the interchain transfer. + * @param amount the amount of token to give. + * @param metadata the data to be passed to the destination. If provided with a bytes4(0) prefix, it'll execute the destination contract. + */ function interchainTransfer( bytes32 tokenId, string calldata destinationChain, bytes calldata destinationAddress, uint256 amount, bytes calldata metadata - ) external notPaused { + ) external payable notPaused { ITokenManager tokenManager = ITokenManager(getTokenManagerAddress(tokenId)); amount = tokenManager.takeToken(msg.sender, amount); _transmitSendToken(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadata); @@ -493,7 +500,7 @@ contract InterchainTokenService is bytes calldata destinationAddress, uint256 amount, bytes calldata data - ) external notPaused { + ) external payable notPaused { ITokenManager tokenManager = ITokenManager(getTokenManagerAddress(tokenId)); amount = tokenManager.takeToken(msg.sender, amount); uint32 prefix = 0; diff --git a/contracts/interfaces/ICanonicalTokenRegistrar.sol b/contracts/interfaces/ICanonicalTokenRegistrar.sol new file mode 100644 index 00000000..73459c76 --- /dev/null +++ b/contracts/interfaces/ICanonicalTokenRegistrar.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface ICanonicalTokenRegistrar { + error ZeroAddress(); + error ApproveFailed(); + + function chainNameHash() external view returns (bytes32); + + function getCanonicalTokenSalt(address tokenAddress) external view returns (bytes32 salt); + + function getCanonicalTokenId(address tokenAddress) external view returns (bytes32 tokenId); + + function registerCanonicalToken(address tokenAddress) external payable returns (bytes32 tokenId); + + function deployAndRegisterRemoteCanonicalToken(bytes32 salt, string calldata destinationChain, uint256 gasValue) external payable; +} diff --git a/contracts/interfaces/IDistributable.sol b/contracts/interfaces/IDistributable.sol index 66406480..d47b017a 100644 --- a/contracts/interfaces/IDistributable.sol +++ b/contracts/interfaces/IDistributable.sol @@ -2,7 +2,9 @@ pragma solidity ^0.8.0; -interface IDistributable { +import { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol'; + +interface IDistributable is IRolesBase { /** * @notice Change the distributor of the contract * @dev Can only be called by the current distributor diff --git a/contracts/interfaces/IInterchainTokenService.sol b/contracts/interfaces/IInterchainTokenService.sol index 7656c3da..8f7ea8c4 100644 --- a/contracts/interfaces/IInterchainTokenService.sol +++ b/contracts/interfaces/IInterchainTokenService.sol @@ -8,6 +8,7 @@ import { IContractIdentifier } from '@axelar-network/axelar-gmp-sdk-solidity/con import { ITokenManagerType } from './ITokenManagerType.sol'; import { IPausable } from './IPausable.sol'; import { IMulticall } from './IMulticall.sol'; +import { IRemoteAddressValidator } from './IRemoteAddressValidator.sol'; interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExecutable, IPausable, IMulticall, IContractIdentifier { error ZeroAddress(); @@ -82,6 +83,12 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec ); event CustomTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); + /** + * @notice Returns the address of the token manager deployer contract. + * @return remoteAddressValidator_ The remoteAddressValidator. + */ + function remoteAddressValidator() external view returns (IRemoteAddressValidator remoteAddressValidator_); + /** * @notice Returns the address of the token manager deployer contract. * @return tokenManagerDeployerAddress The address of the token manager deployer contract. @@ -238,7 +245,7 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec bytes calldata destinationAddress, uint256 amount, bytes calldata metadata - ) external; + ) external payable; function sendTokenWithData( bytes32 tokenId, @@ -246,7 +253,7 @@ interface IInterchainTokenService is ITokenManagerType, IAxelarValuedExpressExec bytes calldata destinationAddress, uint256 amount, bytes calldata data - ) external; + ) external payable; /** * @notice Initiates an interchain token transfer. Only callable by TokenManagers diff --git a/contracts/interfaces/IOperatable.sol b/contracts/interfaces/IOperatable.sol index 186ffe4b..db922286 100644 --- a/contracts/interfaces/IOperatable.sol +++ b/contracts/interfaces/IOperatable.sol @@ -2,7 +2,9 @@ pragma solidity ^0.8.0; -interface IOperatable { +import { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol'; + +interface IOperatable is IRolesBase { /** * @notice Change the operator of the contract * @dev Can only be called by the current operator diff --git a/contracts/interfaces/IStandardizedToken.sol b/contracts/interfaces/IStandardizedToken.sol index bf9c17fd..8f8762a8 100644 --- a/contracts/interfaces/IStandardizedToken.sol +++ b/contracts/interfaces/IStandardizedToken.sol @@ -2,20 +2,34 @@ pragma solidity ^0.8.0; -import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; import { IContractIdentifier } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IContractIdentifier.sol'; -import { IImplementation } from './IImplementation.sol'; import { IInterchainToken } from './IInterchainToken.sol'; import { IDistributable } from './IDistributable.sol'; import { IERC20MintableBurnable } from './IERC20MintableBurnable.sol'; +import { ITokenManager } from './ITokenManager.sol'; +import { IERC20Named } from './IERC20Named.sol'; /** * @title StandardizedToken * @notice This contract implements a standardized token which extends InterchainToken functionality. * This contract also inherits Distributable and Implementation logic. */ -interface IStandardizedToken is IImplementation, IInterchainToken, IDistributable, IERC20MintableBurnable, IERC20, IContractIdentifier { +interface IStandardizedToken is IInterchainToken, IDistributable, IERC20MintableBurnable, IERC20Named, IContractIdentifier { error TokenManagerAddressZero(); error TokenNameEmpty(); + + /** + * @notice Called by the proxy to setup itself. + * @dev This should be hidden by the proxy. + * @param params the data to be used for the initialization. + */ + function setup(bytes calldata params) external; + + /** + * @notice Getter for the tokenManager used for this token. + * @dev Needs to be overwitten. + * @return tokenManager_ the TokenManager called to facilitate cross chain transfers. + */ + function tokenManager() external view returns (ITokenManager tokenManager_); } diff --git a/contracts/interfaces/IStandardizedTokenDeployer.sol b/contracts/interfaces/IStandardizedTokenDeployer.sol index 147c01c9..2601b04d 100644 --- a/contracts/interfaces/IStandardizedTokenDeployer.sol +++ b/contracts/interfaces/IStandardizedTokenDeployer.sol @@ -2,8 +2,6 @@ pragma solidity ^0.8.0; -import { Create3Deployer } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/Create3Deployer.sol'; - /** * @title IStandardizedTokenDeployer * @notice This contract is used to deploy new instances of the StandardizedTokenProxy contract. diff --git a/contracts/interfaces/IStandardizedTokenRegistrar.sol b/contracts/interfaces/IStandardizedTokenRegistrar.sol new file mode 100644 index 00000000..1a0d6018 --- /dev/null +++ b/contracts/interfaces/IStandardizedTokenRegistrar.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface IStandardizedTokenRegistrar { + error ZeroAddress(); + error NotDistributor(address distributor); + error NotOperator(address operator); + error NonZeroMintAmount(); + + function chainNameHash() external view returns (bytes32); + + function getStandardizedTokenSalt(address deployer, bytes32 salt) external view returns (bytes32); + + function getStandardizedTokenId(address deployer, bytes32 salt) external view returns (bytes32 tokenId); + + function getStandardizedTokenAddress(address deployer, bytes32 salt) external view returns (address tokenAddress); + + function deployStandardizedToken( + bytes32 salt, + string calldata name, + string calldata symbol, + uint8 decimals, + uint256 mintAmount, + address distributor + ) external payable; + + function deployRemoteStandarizedToken( + bytes32 salt, + address additionalDistributor, + address optionalOperator, + uint256 mintAmount, + string memory destinationChain, + uint256 gasValue + ) external payable; +} diff --git a/contracts/interfaces/ITokenManagerDeployer.sol b/contracts/interfaces/ITokenManagerDeployer.sol index c3e8cbf8..2379fe42 100644 --- a/contracts/interfaces/ITokenManagerDeployer.sol +++ b/contracts/interfaces/ITokenManagerDeployer.sol @@ -2,8 +2,6 @@ pragma solidity ^0.8.0; -import { Create3Deployer } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/Create3Deployer.sol'; - /** * @title ITokenManagerDeployer * @notice This contract is used to deploy new instances of the TokenManagerProxy contract. diff --git a/contracts/proxies/CanonicalTokenRegistrarProxy.sol b/contracts/proxies/CanonicalTokenRegistrarProxy.sol new file mode 100644 index 00000000..2823a93a --- /dev/null +++ b/contracts/proxies/CanonicalTokenRegistrarProxy.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import { Proxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Proxy.sol'; + +/** + * @title CanonicalTokenRegistrarProxy + * @dev Proxy contract for interchain token service contracts. Inherits from the Proxy contract. + */ +contract CanonicalTokenRegistrarProxy is Proxy { + bytes32 private constant CONTRACT_ID = keccak256('canonical-token-registrar'); + + /** + * @dev Constructs the InterchainTokenServiceProxy contract. + * @param implementationAddress Address of the interchain token service implementation + * @param owner Address of the owner of the proxy + */ + constructor(address implementationAddress, address owner) Proxy(implementationAddress, owner, '') {} + + /** + * @dev Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract. + * @return bytes32 identifier for this contract + */ + function contractId() internal pure override returns (bytes32) { + return CONTRACT_ID; + } +} diff --git a/contracts/proxies/StandardizedTokenRegistrarProxy.sol b/contracts/proxies/StandardizedTokenRegistrarProxy.sol new file mode 100644 index 00000000..ffbbc038 --- /dev/null +++ b/contracts/proxies/StandardizedTokenRegistrarProxy.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import { Proxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Proxy.sol'; + +/** + * @title StandardizedTokenRegistrarProxy + * @dev Proxy contract for interchain token service contracts. Inherits from the Proxy contract. + */ +contract StandardizedTokenRegistrarProxy is Proxy { + bytes32 private constant CONTRACT_ID = keccak256('standardized-token-registrar'); + + /** + * @dev Constructs the InterchainTokenServiceProxy contract. + * @param implementationAddress Address of the interchain token service implementation + * @param owner Address of the owner of the proxy + */ + constructor(address implementationAddress, address owner) Proxy(implementationAddress, owner, '') {} + + /** + * @dev Override for the 'contractId' function in FinalProxy. Returns a unique identifier for this contract. + * @return bytes32 identifier for this contract + */ + function contractId() internal pure override returns (bytes32) { + return CONTRACT_ID; + } +} diff --git a/contracts/test/HardCodedConstantsTest.sol b/contracts/test/HardCodedConstantsTest.sol index 2ff0e1e8..4ce633b9 100644 --- a/contracts/test/HardCodedConstantsTest.sol +++ b/contracts/test/HardCodedConstantsTest.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT +// solhint-disable-next-line one-contract-per-file pragma solidity ^0.8.0; import { TokenManagerLiquidityPool } from '../token-manager/implementations/TokenManagerLiquidityPool.sol'; @@ -9,12 +10,14 @@ import { NoReEntrancy } from '../utils/NoReEntrancy.sol'; import { Operatable } from '../utils/Operatable.sol'; import { Pausable } from '../utils/Pausable.sol'; +error Invalid(); + contract TestTokenManager is TokenManagerLiquidityPool { string public constant NAME = 'TestTokenManager'; constructor(address interchainTokenService_) TokenManagerLiquidityPool(interchainTokenService_) { - require(TOKEN_ADDRESS_SLOT == uint256(keccak256('token-address')) - 1, 'invalid constant'); - require(LIQUIDITY_POOL_SLOT == uint256(keccak256('liquidity-pool-slot')) - 1, 'invalid constant'); + if (TOKEN_ADDRESS_SLOT != uint256(keccak256('token-address')) - 1) revert Invalid(); + if (LIQUIDITY_POOL_SLOT != uint256(keccak256('liquidity-pool-slot')) - 1) revert Invalid(); } } @@ -28,7 +31,7 @@ contract TestFlowLimit is FlowLimit { string public constant NAME = 'TestFlowLimit'; constructor() { - require(FLOW_LIMIT_SLOT == uint256(keccak256('flow-limit')) - 1, 'invalid constant'); + if (FLOW_LIMIT_SLOT != uint256(keccak256('flow-limit')) - 1) revert Invalid(); } } @@ -36,7 +39,7 @@ contract TestNoReEntrancy is NoReEntrancy { string public constant NAME = 'TestNoReEntrancy'; constructor() { - require(ENTERED_SLOT == uint256(keccak256('entered')) - 1, 'invalid constant'); + if (ENTERED_SLOT != uint256(keccak256('entered')) - 1) revert Invalid(); } } @@ -50,6 +53,6 @@ contract TestPausable is Pausable { string public constant NAME = 'TestPausable'; constructor() { - require(PAUSE_SLOT == uint256(keccak256('paused')) - 1, 'invalid constant'); + if (PAUSE_SLOT != uint256(keccak256('paused')) - 1) revert Invalid(); } } diff --git a/contracts/test/InterchainExecutableTest.sol b/contracts/test/InterchainExecutableTest.sol index 5ea53999..9902700c 100644 --- a/contracts/test/InterchainExecutableTest.sol +++ b/contracts/test/InterchainExecutableTest.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.0; import { InterchainTokenExpressExecutable } from '../executable/InterchainTokenExpressExecutable.sol'; -import { IInterchainTokenService } from '../interfaces/IInterchainTokenService.sol'; import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; contract InterchainExecutableTest is InterchainTokenExpressExecutable { diff --git a/contracts/test/utils/MulticallTest.sol b/contracts/test/utils/MulticallTest.sol index 66d39010..5a6735dc 100644 --- a/contracts/test/utils/MulticallTest.sol +++ b/contracts/test/utils/MulticallTest.sol @@ -23,7 +23,7 @@ contract MulticallTest is Multicall { } function function3() external pure { - // solhint-disable-next-line reason-string + // solhint-disable-next-line reason-string,custom-errors revert(); } diff --git a/contracts/token-implementations/StandardizedToken.sol b/contracts/token-implementations/StandardizedToken.sol index fd3b040e..c2db2c13 100644 --- a/contracts/token-implementations/StandardizedToken.sol +++ b/contracts/token-implementations/StandardizedToken.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.0; +import { IImplementation } from '../interfaces/IImplementation.sol'; import { IStandardizedToken } from '../interfaces/IStandardizedToken.sol'; import { ITokenManager } from '../interfaces/ITokenManager.sol'; -import { IInterchainToken } from '../interfaces/IInterchainToken.sol'; import { InterchainToken } from '../interchain-token/InterchainToken.sol'; import { ERC20Permit } from '../token-implementations/ERC20Permit.sol'; @@ -38,7 +38,7 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist * @notice Returns the token manager for this token * @return ITokenManager The token manager contract */ - function tokenManager() public view override(InterchainToken, IInterchainToken) returns (ITokenManager) { + function tokenManager() public view override(InterchainToken, IStandardizedToken) returns (ITokenManager) { return ITokenManager(tokenManager_); } @@ -47,7 +47,7 @@ contract StandardizedToken is InterchainToken, ERC20Permit, Implementation, Dist * @param params The setup parameters in bytes * The setup params include tokenManager, distributor, tokenName, symbol, decimals, mintAmount and mintTo */ - function setup(bytes calldata params) external override onlyProxy { + function setup(bytes calldata params) external override(IImplementation, IStandardizedToken) onlyProxy { { address distributor_; address tokenManagerAddress; diff --git a/contracts/token-manager/TokenManager.sol b/contracts/token-manager/TokenManager.sol index 063b67ba..22d218a6 100644 --- a/contracts/token-manager/TokenManager.sol +++ b/contracts/token-manager/TokenManager.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.0; import { ITokenManager } from '../interfaces/ITokenManager.sol'; import { IInterchainTokenService } from '../interfaces/IInterchainTokenService.sol'; -import { ITokenManagerProxy } from '../interfaces/ITokenManagerProxy.sol'; import { Operatable } from '../utils/Operatable.sol'; import { FlowLimit } from '../utils/FlowLimit.sol'; diff --git a/contracts/token-manager/implementations/TokenManagerLiquidityPool.sol b/contracts/token-manager/implementations/TokenManagerLiquidityPool.sol index 9ac153b1..47c5ebf1 100644 --- a/contracts/token-manager/implementations/TokenManagerLiquidityPool.sol +++ b/contracts/token-manager/implementations/TokenManagerLiquidityPool.sol @@ -19,6 +19,8 @@ import { NoReEntrancy } from '../../utils/NoReEntrancy.sol'; contract TokenManagerLiquidityPool is TokenManager, NoReEntrancy, ITokenManagerLiquidityPool { using SafeTokenTransferFrom for IERC20; + error NotSupported(); + // uint256(keccak256('liquidity-pool-slot')) - 1 uint256 internal constant LIQUIDITY_POOL_SLOT = 0x8e02741a3381812d092c5689c9fc701c5185c1742fdf7954c4c4472be4cc4807; @@ -30,7 +32,7 @@ contract TokenManagerLiquidityPool is TokenManager, NoReEntrancy, ITokenManagerL constructor(address interchainTokenService_) TokenManager(interchainTokenService_) {} function implementationType() external pure returns (uint256) { - revert('Not supported'); + revert NotSupported(); } /** diff --git a/contracts/token-registrars/CanonicalTokenRegistrar.sol b/contracts/token-registrars/CanonicalTokenRegistrar.sol new file mode 100644 index 00000000..1f633089 --- /dev/null +++ b/contracts/token-registrars/CanonicalTokenRegistrar.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; +import { SafeTokenTransferFrom } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol'; +import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; + +import { IInterchainTokenService } from '../interfaces/IInterchainTokenService.sol'; +import { ICanonicalTokenRegistrar } from '../interfaces/ICanonicalTokenRegistrar.sol'; +import { ITokenManagerType } from '../interfaces/ITokenManagerType.sol'; +import { IERC20Named } from '../interfaces/IERC20Named.sol'; + +import { Multicall } from '../utils/Multicall.sol'; + +contract CanonicalTokenRegistrar is ICanonicalTokenRegistrar, ITokenManagerType, Multicall, Upgradable { + using SafeTokenTransferFrom for IERC20; + + IInterchainTokenService public immutable service; + bytes32 public immutable chainNameHash; + + bytes32 internal constant PREFIX_CANONICAL_TOKEN_SALT = keccak256('canonical-token-salt'); + bytes32 private constant CONTRACT_ID = keccak256('canonical-token-registrar'); + + constructor(address interchainTokenServiceAddress) { + if (interchainTokenServiceAddress == address(0)) revert ZeroAddress(); + service = IInterchainTokenService(interchainTokenServiceAddress); + string memory chainName_ = IInterchainTokenService(interchainTokenServiceAddress).remoteAddressValidator().chainName(); + chainNameHash = keccak256(bytes(chainName_)); + } + + /** + * @notice Getter for the contract id. + */ + function contractId() external pure returns (bytes32) { + return CONTRACT_ID; + } + + function getCanonicalTokenSalt(address tokenAddress) public view returns (bytes32 salt) { + salt = keccak256(abi.encode(PREFIX_CANONICAL_TOKEN_SALT, chainNameHash, tokenAddress)); + } + + function getCanonicalTokenId(address tokenAddress) public view returns (bytes32 tokenId) { + tokenId = service.getCustomTokenId(address(this), getCanonicalTokenSalt(tokenAddress)); + } + + function registerCanonicalToken(address tokenAddress) external payable returns (bytes32 tokenId) { + bytes memory params = abi.encode('', tokenAddress); + bytes32 salt = getCanonicalTokenSalt(tokenAddress); + tokenId = service.deployCustomTokenManager(salt, TokenManagerType.LOCK_UNLOCK, params); + } + + function deployAndRegisterRemoteCanonicalToken(bytes32 salt, string calldata destinationChain, uint256 gasValue) external payable { + // This ensures that the token manages has been deployed by this address, so it's safe to trust it. + bytes32 tokenId = service.getCustomTokenId(address(this), salt); + IERC20Named token = IERC20Named(service.getTokenAddress(tokenId)); + // The 3 lines below will revert if the token manager does not exist. + string memory tokenName = token.name(); + string memory tokenSymbol = token.symbol(); + uint8 tokenDecimals = token.decimals(); + + // slither-disable-next-line arbitrary-send-eth + service.deployAndRegisterRemoteStandardizedToken{ value: gasValue }( + salt, + tokenName, + tokenSymbol, + tokenDecimals, + '', + '', + 0, + '', + destinationChain, + gasValue + ); + } + + function transferCanonicalToken( + address tokenAddress, + string calldata destinationChain, + bytes calldata destinationAddress, + uint256 amount, + uint256 gasValue + ) external payable { + // This ensures that the token manager has been deployed by this address, so it's safe to trust it. + bytes32 tokenId = getCanonicalTokenId(tokenAddress); + // slither-disable-next-line unused-return + service.getValidTokenManagerAddress(tokenId); + IERC20 token = IERC20(tokenAddress); + + token.safeTransferFrom(msg.sender, address(this), amount); + + address tokenManagerAddress = service.getTokenManagerAddress(tokenId); + if (!token.approve(tokenManagerAddress, amount)) revert ApproveFailed(); + + // slither-disable-next-line arbitrary-send-eth + service.interchainTransfer{ value: gasValue }(tokenId, destinationChain, destinationAddress, amount, bytes('')); + } +} diff --git a/contracts/token-registrars/StandardizedTokenRegistrar.sol b/contracts/token-registrars/StandardizedTokenRegistrar.sol new file mode 100644 index 00000000..7e823092 --- /dev/null +++ b/contracts/token-registrars/StandardizedTokenRegistrar.sol @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import { SafeTokenTransfer } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol'; +import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; + +import { IInterchainTokenService } from '../interfaces/IInterchainTokenService.sol'; +import { IStandardizedTokenRegistrar } from '../interfaces/IStandardizedTokenRegistrar.sol'; +import { ITokenManagerType } from '../interfaces/ITokenManagerType.sol'; +import { ITokenManager } from '../interfaces/ITokenManager.sol'; +import { IStandardizedToken } from '../interfaces/IStandardizedToken.sol'; + +import { Multicall } from '../utils/Multicall.sol'; + +import { AddressBytesUtils } from '../libraries/AddressBytesUtils.sol'; + +contract StandardizedTokenRegistrar is IStandardizedTokenRegistrar, ITokenManagerType, Multicall, Upgradable { + using AddressBytesUtils for bytes; + using AddressBytesUtils for address; + using SafeTokenTransfer for IStandardizedToken; + + IInterchainTokenService public immutable service; + bytes32 public immutable chainNameHash; + + bytes32 private constant CONTRACT_ID = keccak256('standardized-token-registrar'); + + struct DeployParams { + address deployer; + bytes distributor; + bytes operator; + } + + mapping(bytes32 => DeployParams) public deploymentParameterMap; + + bytes32 internal constant PREFIX_STANDARDIZED_TOKEN_SALT = keccak256('standardized-token-salt'); + + constructor(address interchainTokenServiceAddress) { + if (interchainTokenServiceAddress == address(0)) revert ZeroAddress(); + service = IInterchainTokenService(interchainTokenServiceAddress); + string memory chainName_ = IInterchainTokenService(interchainTokenServiceAddress).remoteAddressValidator().chainName(); + chainNameHash = keccak256(bytes(chainName_)); + } + + /** + * @notice Getter for the contract id. + */ + function contractId() external pure returns (bytes32) { + return CONTRACT_ID; + } + + function getStandardizedTokenSalt(address deployer, bytes32 salt) public view returns (bytes32) { + return keccak256(abi.encode(PREFIX_STANDARDIZED_TOKEN_SALT, chainNameHash, deployer, salt)); + } + + function getStandardizedTokenId(address deployer, bytes32 salt) public view returns (bytes32 tokenId) { + tokenId = service.getCustomTokenId(address(this), getStandardizedTokenSalt(deployer, salt)); + } + + function getStandardizedTokenAddress(address deployer, bytes32 salt) public view returns (address tokenAddress) { + tokenAddress = service.getStandardizedTokenAddress(getStandardizedTokenId(deployer, salt)); + } + + function deployStandardizedToken( + bytes32 salt, + string calldata name, + string calldata symbol, + uint8 decimals, + uint256 mintAmount, + address distributor + ) external payable { + address sender = msg.sender; + salt = getStandardizedTokenSalt(sender, salt); + bytes32 tokenId = service.getCustomTokenId(address(this), salt); + + service.deployAndRegisterStandardizedToken(salt, name, symbol, decimals, mintAmount, distributor); + ITokenManager tokenManager = ITokenManager(service.getTokenManagerAddress(tokenId)); + tokenManager.transferOperatorship(sender); + + IStandardizedToken token = IStandardizedToken(service.getStandardizedTokenAddress(tokenId)); + token.safeTransfer(sender, mintAmount); + } + + function deployRemoteStandarizedToken( + bytes32 salt, + address additionalDistributor, + address optionalOperator, + uint256 mintAmount, + string memory destinationChain, + uint256 gasValue + ) external payable { + string memory tokenName; + string memory tokenSymbol; + uint8 tokenDecimals; + bytes memory distributor = new bytes(0); + bytes memory operator = new bytes(0); + + { + address sender = msg.sender; + salt = getStandardizedTokenSalt(sender, salt); + bytes32 tokenId = service.getCustomTokenId(address(this), salt); + + IStandardizedToken token = IStandardizedToken(service.getStandardizedTokenAddress(tokenId)); + ITokenManager tokenManager = ITokenManager(service.getTokenManagerAddress(tokenId)); + + tokenName = token.name(); + tokenSymbol = token.symbol(); + tokenDecimals = token.decimals(); + if (additionalDistributor != address(0)) { + if (!token.isDistributor(additionalDistributor)) revert NotDistributor(additionalDistributor); + distributor = additionalDistributor.toBytes(); + } else if (mintAmount != 0) { + revert NonZeroMintAmount(); + } + if (optionalOperator != address(0)) { + if (!tokenManager.isOperator(optionalOperator)) revert NotOperator(optionalOperator); + operator = optionalOperator.toBytes(); + } + } + + _deployAndRegisterRemoteStandardizedToken( + salt, + tokenName, + tokenSymbol, + tokenDecimals, + distributor, + operator, + mintAmount, + destinationChain, + gasValue + ); + } + + function _deployAndRegisterRemoteStandardizedToken( + bytes32 salt, + string memory tokenName, + string memory tokenSymbol, + uint8 tokenDecimals, + bytes memory distributor, + bytes memory operator, + uint256 mintAmount, + string memory destinationChain, + uint256 gasValue + ) internal { + // slither-disable-next-line arbitrary-send-eth + service.deployAndRegisterRemoteStandardizedToken{ value: gasValue }( + salt, + tokenName, + tokenSymbol, + tokenDecimals, + distributor, + '', + mintAmount, + operator, + destinationChain, + gasValue + ); + } +} diff --git a/package-lock.json b/package-lock.json index 37c1f028..442fd10b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,34 +71,35 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -170,23 +171,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -202,14 +203,55 @@ } }, "node_modules/@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "node_modules/@ethersproject/abi": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", @@ -911,10 +953,19 @@ "@ethersproject/strings": "^5.7.0" } }, + "node_modules/@fastify/busboy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", + "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1018,17 +1069,31 @@ "rlp": "^2.2.3" } }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@noble/secp256k1": { "version": "1.7.1", @@ -1302,9 +1367,9 @@ } }, "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz", - "integrity": "sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.9.tgz", + "integrity": "sha512-OXWCv0cHpwLUO2u7bFxBna6dQtCC2Gg/aN/KtJLO7gmuuA28vgmVKYFRCDUqrbjujzgfwQ2aKyZ9Y3vSmDqS7Q==", "dev": true, "peer": true, "dependencies": { @@ -1591,48 +1656,41 @@ } }, "node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", + "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "peer": true, "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "peer": true, "dependencies": { - "@noble/hashes": "~1.2.0", + "@noble/hashes": "~1.3.0", "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@sentry/core": { @@ -1828,25 +1886,25 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-/k+vesl92vMvMygmQrFe9Aimxi6oQXFUX9mA5HanTrKUSAMoLauSi6PNFOdRw0oeqilaW600GNx2vSaT2f8aIQ==", "dev": true, "peer": true }, "node_modules/@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.6.tgz", + "integrity": "sha512-cQLhk8fFarRVZAXUQV1xEnZgMoPxqKojBvRkqPCKPQCzEhpbbSKl1Uu75kDng7k5Ln6LQLUmNBjLlFthCgm1NA==", "dev": true, "peer": true, "dependencies": { @@ -1904,17 +1962,20 @@ "peer": true }, "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.2.tgz", + "integrity": "sha512-NaHL0+0lLNhX6d9rs+NSt97WH/gIlRHmszXbQ/8/MV/eVcFNdeJ/GYhrFuUc8K7WuPhRhTSdMkCp8VMzhUq85w==", "dev": true, "peer": true }, "node_modules/@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==", - "dev": true + "version": "20.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", + "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "dev": true, + "dependencies": { + "undici-types": "~5.25.1" + } }, "node_modules/@types/pbkdf2": { "version": "3.1.0", @@ -1933,9 +1994,9 @@ "peer": true }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", "dev": true, "peer": true }, @@ -1956,9 +2017,9 @@ "dev": true }, "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.4.tgz", + "integrity": "sha512-oN0PFsYxDZnX/qSJ5S5OwaEDTYfekhvaM5vqui2bu1AA39pKofmgL104Q29KiOXizXS2yLjSzc5YdTyMKdcy4A==", "dev": true, "dependencies": { "@types/node": "*" @@ -1990,9 +2051,9 @@ } }, "node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2155,9 +2216,9 @@ } }, "node_modules/antlr4": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.0.tgz", - "integrity": "sha512-zooUbt+UscjnWyOrsuY/tVFL4rwrAGwOivpQmvmUDE22hy/lUA467Rc1rcixyRwcRUIXFYBwv7+dClDSHdmmew==", + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.1.tgz", + "integrity": "sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA==", "dev": true, "engines": { "node": ">=16" @@ -2219,15 +2280,15 @@ } }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" }, "engines": { @@ -2257,15 +2318,53 @@ "node": ">=0.10.0" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.3.tgz", + "integrity": "sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -2276,14 +2375,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -2293,6 +2392,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -2372,21 +2492,6 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/axios/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "peer": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2574,18 +2679,6 @@ "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", "dev": true }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dev": true, - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2668,18 +2761,18 @@ } }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -2723,10 +2816,13 @@ } }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } @@ -2987,6 +3083,13 @@ "typedarray": "^0.0.6" } }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "peer": true + }, "node_modules/concat-stream/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -3030,21 +3133,21 @@ } }, "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true, "peer": true }, "node_modules/cosmiconfig": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "dependencies": { - "import-fresh": "^3.2.1", + "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", + "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "engines": { @@ -3052,6 +3155,14 @@ }, "funding": { "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/crc-32": { @@ -3206,12 +3317,27 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -3343,12 +3469,13 @@ "dev": true }, "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8.6" @@ -3373,18 +3500,19 @@ } }, "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", + "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.1", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", @@ -3399,19 +3527,23 @@ "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -3567,27 +3699,27 @@ } }, "node_modules/eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.51.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -3597,7 +3729,6 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -3607,9 +3738,8 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -3666,14 +3796,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -3731,26 +3861,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, "dependencies": { "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", "array.prototype.flat": "^1.3.1", "array.prototype.flatmap": "^1.3.1", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", + "eslint-module-utils": "^2.8.0", "has": "^1.0.3", - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" }, "engines": { "node": ">=4" @@ -3849,9 +3981,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -3889,9 +4021,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3983,12 +4115,12 @@ } }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -4085,6 +4217,54 @@ } } }, + "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", @@ -4295,9 +4475,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "peer": true, "dependencies": { @@ -4408,28 +4588,29 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, "funding": [ { @@ -4456,18 +4637,18 @@ } }, "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "peer": true, "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, "node_modules/fp-ts": { @@ -4504,9 +4685,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -4524,15 +4705,15 @@ "dev": true }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -4712,9 +4893,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -4786,13 +4967,13 @@ "dev": true }, "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "dependencies": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, @@ -4816,9 +4997,9 @@ } }, "node_modules/hardhat": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.18.0.tgz", - "integrity": "sha512-Com3SPFgk6v73LlE3rypuh32DYxOWvNbVBm5xfPUEzGVEW54Fcc4j3Uq7j6COj7S8Jc27uNihLFsveHYM0YJkQ==", + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.18.1.tgz", + "integrity": "sha512-b55rW7Ka+fvJeg6oWuBTXoYQEUurevCCankjGNTwczwD3GnkhV9GEei7KUT+9IKmWx3lC+zyxlFxeDbg0gUoHw==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", @@ -5002,25 +5183,70 @@ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", + "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", + "dev": true, + "peer": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" } }, - "node_modules/hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", "dev": true, - "peer": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - }, - "peerDependencies": { - "hardhat": "^2.0.2" + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" } }, "node_modules/hardhat/node_modules/ethereum-cryptography": { @@ -5107,15 +5333,6 @@ "node": ">=4" } }, - "node_modules/hardhat/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/hardhat/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -5147,13 +5364,10 @@ } }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, "engines": { "node": ">= 0.4.0" } @@ -5382,9 +5596,9 @@ } }, "node_modules/immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", "dev": true }, "node_modules/import-fresh": { @@ -5573,9 +5787,9 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -5753,16 +5967,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -5796,11 +6006,10 @@ } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "peer": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -5842,6 +6051,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -5895,9 +6110,9 @@ } }, "node_modules/keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -5909,6 +6124,15 @@ "node": ">=10.0.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -6203,6 +6427,13 @@ "node": ">= 8" } }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "peer": true + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -6469,9 +6700,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", + "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", "dev": true, "bin": { "node-gyp-build": "bin.js", @@ -6579,15 +6810,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -6689,6 +6949,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6866,9 +7135,9 @@ } }, "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", - "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", + "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", "dev": true, "dependencies": { "antlr4ts": "^0.5.0-alpha.4" @@ -6887,9 +7156,9 @@ } }, "node_modules/prettier-plugin-solidity/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6941,13 +7210,19 @@ } }, "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "dev": true, "peer": true, + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/queue-microtask": { @@ -7063,14 +7338,14 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "set-function-name": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -7146,12 +7421,12 @@ } }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -7270,6 +7545,24 @@ "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", "dev": true }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7473,6 +7766,20 @@ "randombytes": "^2.1.0" } }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -7701,9 +8008,9 @@ } }, "node_modules/solhint": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.4.1.tgz", - "integrity": "sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.6.2.tgz", + "integrity": "sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ==", "dev": true, "dependencies": { "@solidity-parser/parser": "^0.16.0", @@ -7719,7 +8026,7 @@ "js-yaml": "^4.1.0", "lodash": "^4.17.21", "pluralize": "^8.0.0", - "semver": "^6.3.0", + "semver": "^7.5.2", "strip-ansi": "^6.0.1", "table": "^6.8.1", "text-table": "^0.2.0" @@ -7732,9 +8039,9 @@ } }, "node_modules/solhint/node_modules/@solidity-parser/parser": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", - "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", + "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", "dev": true, "dependencies": { "antlr4ts": "^0.5.0-alpha.4" @@ -7835,6 +8142,18 @@ "node": ">=8" } }, + "node_modules/solhint/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/solhint/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -7847,6 +8166,21 @@ "node": ">=10" } }, + "node_modules/solhint/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/solhint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7859,12 +8193,21 @@ "node": ">=8" } }, - "node_modules/solidity-ast": { - "version": "0.4.49", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.49.tgz", - "integrity": "sha512-Pr5sCAj1SFqzwFZw1HPKSq0PehlQNdM8GwKyAVYh2DOn7/cCK8LUKD1HeHnKtTgBW7hi9h4nnnan7hpAg5RhWQ==", + "node_modules/solhint/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/solidity-ast": { + "version": "0.4.52", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.52.tgz", + "integrity": "sha512-iOya9BSiB9jhM8Vf40n8lGELGzwrUc57rl5BhfNtJ5cvAaMvRcNlHeAMNvqJJyjoUnczqRbHqdivEqK89du3Cw==", + "dev": true, + "dependencies": { + "array.prototype.findlast": "^1.2.2" + } + }, "node_modules/solidity-comments-extractor": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", @@ -7907,9 +8250,9 @@ } }, "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", - "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", + "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", "dev": true, "peer": true, "dependencies": { @@ -7955,9 +8298,9 @@ } }, "node_modules/solidity-coverage/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "peer": true, "dependencies": { @@ -8070,15 +8413,6 @@ "node": ">= 0.8" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -8133,14 +8467,14 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -8150,28 +8484,28 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8405,6 +8739,21 @@ "dev": true, "peer": true }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -8664,9 +9013,9 @@ } }, "node_modules/typechain": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.2.0.tgz", - "integrity": "sha512-tZqhqjxJ9xAS/Lh32jccTjMkpx7sTdUVVHAy5Bf0TIer5QFNYXotiX74oCvoVYjyxUKDK3MXHtMFzMyD3kE+jg==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.1.tgz", + "integrity": "sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ==", "dev": true, "peer": true, "dependencies": { @@ -8757,6 +9106,57 @@ "node": ">= 4.0.0" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -8779,9 +9179,9 @@ "peer": true }, "node_modules/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "peer": true, "bin": { @@ -8831,17 +9231,23 @@ } }, "node_modules/undici": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", - "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "version": "5.26.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.3.tgz", + "integrity": "sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==", "dev": true, "dependencies": { - "busboy": "^1.6.0" + "@fastify/busboy": "^2.0.0" }, "engines": { "node": ">=14.0" } }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", + "dev": true + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -8899,15 +9305,16 @@ "peer": true }, "node_modules/web3-utils": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.0.tgz", - "integrity": "sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.2.tgz", + "integrity": "sha512-TdApdzdse5YR+5GCX/b/vQnhhbj1KSAtfrDtRW7YS0kcWp1gkJsN62gw6GzCaNTeXookB7UrLtmDUuMv65qgow==", "dev": true, "peer": true, "dependencies": { + "@ethereumjs/util": "^8.1.0", "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", + "ethereum-cryptography": "^2.1.2", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", @@ -8917,6 +9324,19 @@ "node": ">=8.0.0" } }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8949,17 +9369,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" diff --git a/scripts/deploy.js b/scripts/deploy.js index d0497186..5d0d66ca 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -2,6 +2,7 @@ const { ethers } = require('hardhat'); const { Contract } = ethers; const { defaultAbiCoder } = ethers.utils; const InterchainTokenServiceProxy = require('../artifacts/contracts/proxies/InterchainTokenServiceProxy.sol/InterchainTokenServiceProxy.json'); +const Create3Deployer = require('@axelar-network/axelar-gmp-sdk-solidity/artifacts/contracts/deploy/Create3Deployer.sol/Create3Deployer.json'); const { create3DeployContract, getCreate3Address } = require('@axelar-network/axelar-gmp-sdk-solidity'); async function deployContract(wallet, contractName, args = []) { @@ -75,7 +76,9 @@ async function deployTokenManagerImplementations(wallet, interchainTokenServiceA } async function deployAll(wallet, chainName, evmChains = [], deploymentKey = 'interchainTokenService') { - const create3Deployer = await deployContract(wallet, 'Create3Deployer'); + const create3Deployer = await new ethers.ContractFactory(Create3Deployer.abi, Create3Deployer.bytecode, wallet) + .deploy() + .then((d) => d.deployed()); const gateway = await deployMockGateway(wallet); const gasService = await deployGasService(wallet); const tokenManagerDeployer = await deployContract(wallet, 'TokenManagerDeployer', []); diff --git a/test/TokenService.js b/test/TokenService.js index 16b61fea..3304ad9d 100644 --- a/test/TokenService.js +++ b/test/TokenService.js @@ -7,6 +7,7 @@ const { ethers } = require('hardhat'); const { AddressZero, MaxUint256 } = ethers.constants; const { defaultAbiCoder, solidityPack, keccak256, arrayify, hexlify } = ethers.utils; const { Contract, Wallet } = ethers; +const Create3Deployer = require('@axelar-network/axelar-gmp-sdk-solidity/artifacts/contracts/deploy/Create3Deployer.sol/Create3Deployer.json'); const TokenManager = require('../artifacts/contracts/token-manager/TokenManager.sol/TokenManager.json'); const Token = require('../artifacts/contracts/interfaces/IStandardizedToken.sol/IStandardizedToken.json'); const { getCreate3Address } = require('@axelar-network/axelar-gmp-sdk-solidity'); @@ -142,7 +143,9 @@ describe('Interchain Token Service', () => { const deploymentKey = 'interchainTokenService'; before(async () => { - create3Deployer = await deployContract(wallet, 'Create3Deployer'); + create3Deployer = await new ethers.ContractFactory(Create3Deployer.abi, Create3Deployer.bytecode, wallet) + .deploy() + .then((d) => d.deployed()); gateway = await deployMockGateway(wallet); gasService = await deployGasService(wallet); tokenManagerDeployer = await deployContract(wallet, 'TokenManagerDeployer', []); diff --git a/test/tokenRegistrars.js b/test/tokenRegistrars.js new file mode 100644 index 00000000..95410266 --- /dev/null +++ b/test/tokenRegistrars.js @@ -0,0 +1,316 @@ +'use strict'; + +const chai = require('chai'); +const { expect } = chai; +require('dotenv').config(); +const { ethers } = require('hardhat'); +const { defaultAbiCoder, keccak256 } = ethers.utils; +const { + Contract, + constants: { AddressZero }, +} = ethers; + +const ITokenManager = require('../artifacts/contracts/interfaces/ITokenManager.sol/ITokenManager.json'); +const IERC20 = require('../artifacts/@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol/IERC20.json'); + +const { deployAll, deployContract } = require('../scripts/deploy'); + +// const SELECTOR_SEND_TOKEN_WITH_DATA = 2; +// const SELECTOR_DEPLOY_TOKEN_MANAGER = 3; +const SELECTOR_DEPLOY_AND_REGISTER_STANDARDIZED_TOKEN = 4; + +const LOCK_UNLOCK = 2; +const MINT_BURN = 0; + +// const DISTRIBUTOR_ROLE = 0; +const OPERATOR_ROLE = 1; + +describe('Token Registrsrs', () => { + let wallet; + let service, gateway, gasService, canonicalTokenRegistrar, standardizedTokenRegistrar; + const name = 'tokenName'; + const symbol = 'tokenSymbol'; + const decimals = 18; + const destinationChain = 'destination chain'; + + before(async () => { + const wallets = await ethers.getSigners(); + wallet = wallets[0]; + [service, gateway, gasService] = await deployAll(wallet, 'Test', [destinationChain]); + let proxy, factory; + + canonicalTokenRegistrar = await deployContract(wallet, 'CanonicalTokenRegistrar', [service.address]); + proxy = await deployContract(wallet, 'CanonicalTokenRegistrarProxy', [canonicalTokenRegistrar.address, wallet.address]); + factory = await ethers.getContractFactory('CanonicalTokenRegistrar', wallet); + canonicalTokenRegistrar = factory.attach(proxy.address); + + standardizedTokenRegistrar = await deployContract(wallet, 'StandardizedTokenRegistrar', [service.address]); + proxy = await deployContract(wallet, 'StandardizedTokenRegistrarProxy', [standardizedTokenRegistrar.address, wallet.address]); + factory = await ethers.getContractFactory('StandardizedTokenRegistrar', wallet); + standardizedTokenRegistrar = factory.attach(proxy.address); + }); + + describe('Canonical Token Registrar', async () => { + let token, tokenId; + const tokenCap = BigInt(1e18); + + async function deployToken() { + token = await deployContract(wallet, 'InterchainTokenTest', [name, symbol, decimals, wallet.address]); + tokenId = await canonicalTokenRegistrar.getCanonicalTokenId(token.address); + const tokenManagerAddress = await service.getTokenManagerAddress(tokenId); + await (await token.mint(wallet.address, tokenCap)).wait(); + await (await token.setTokenManager(tokenManagerAddress)).wait(); + } + + it('Should register a token', async () => { + await deployToken(); + + const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); + + await expect(canonicalTokenRegistrar.registerCanonicalToken(token.address)) + .to.emit(service, 'TokenManagerDeployed') + .withArgs(tokenId, LOCK_UNLOCK, params); + }); + + it('Should initiate a remote standardized token deployment', async () => { + const gasValue = 1234; + + await deployToken(); + + const salt = await canonicalTokenRegistrar.getCanonicalTokenSalt(token.address); + 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'], + ); + + await expect(canonicalTokenRegistrar.registerCanonicalToken(token.address)) + .to.emit(service, 'TokenManagerDeployed') + .withArgs(tokenId, LOCK_UNLOCK, params); + + await expect( + canonicalTokenRegistrar.deployAndRegisterRemoteCanonicalToken(salt, destinationChain, gasValue, { value: gasValue }), + ) + .to.emit(service, 'RemoteStandardizedTokenAndManagerDeploymentInitialized') + .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, '0x', destinationChain, gasValue) + .and.to.emit(gasService, 'NativeGasPaidForContractCall') + .withArgs(service.address, destinationChain, service.address.toLowerCase(), keccak256(payload), gasValue, wallet.address) + .and.to.emit(gateway, 'ContractCall') + .withArgs(service.address, destinationChain, service.address.toLowerCase(), keccak256(payload), payload); + }); + + it('Should transfer some tokens though the registrar as the deployer', async () => { + const destinationAddress = '0x659703'; + const amount = 1234; + const gasValue = 1234; + + await deployToken(); + + const params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); + + await expect(canonicalTokenRegistrar.registerCanonicalToken(token.address)) + .to.emit(service, 'TokenManagerDeployed') + .withArgs(tokenId, LOCK_UNLOCK, params); + + const tokenManagerAddress = await service.getValidTokenManagerAddress(tokenId); + + await (await token.approve(canonicalTokenRegistrar.address, amount)).wait(); + + await expect( + canonicalTokenRegistrar.transferCanonicalToken(token.address, destinationChain, destinationAddress, amount, gasValue, { + value: gasValue, + }), + ) + .to.emit(service, 'TokenSent') + .withArgs(tokenId, destinationChain, destinationAddress, amount) + .to.emit(token, 'Transfer') + .withArgs(wallet.address, canonicalTokenRegistrar.address, amount) + .to.emit(token, 'Transfer') + .withArgs(canonicalTokenRegistrar.address, tokenManagerAddress, amount); + }); + }); + + describe('Standardized Token Registrar', async () => { + let tokenId; + const mintAmount = 1234; + + it('Should register a token', async () => { + const salt = keccak256('0x'); + tokenId = await standardizedTokenRegistrar.getStandardizedTokenId(wallet.address, salt); + const tokenAddress = await standardizedTokenRegistrar.getStandardizedTokenAddress(wallet.address, salt); + const params = defaultAbiCoder.encode(['bytes', 'address'], [standardizedTokenRegistrar.address, tokenAddress]); + const tokenManager = new Contract(await service.getTokenManagerAddress(tokenId), ITokenManager.abi, wallet); + const token = new Contract(tokenAddress, IERC20.abi, wallet); + await expect(standardizedTokenRegistrar.deployStandardizedToken(salt, name, symbol, decimals, mintAmount, wallet.address)) + .to.emit(service, 'StandardizedTokenDeployed') + .withArgs(tokenId, wallet.address, name, symbol, decimals, mintAmount, standardizedTokenRegistrar.address) + .and.to.emit(service, 'TokenManagerDeployed') + .withArgs(tokenId, MINT_BURN, params) + .and.to.emit(token, 'Transfer') + .withArgs(standardizedTokenRegistrar.address, wallet.address, mintAmount) + .and.to.emit(tokenManager, 'RolesAdded') + .withArgs(wallet.address, 1 << OPERATOR_ROLE) + .and.to.emit(tokenManager, 'RolesRemoved') + .withArgs(standardizedTokenRegistrar.address, 1 << OPERATOR_ROLE); + }); + + it('Should initiate a remote standardized token deployment with the same distributor', async () => { + const gasValue = 1234; + const mintAmount = 5678; + + const salt = keccak256('0x12'); + tokenId = await standardizedTokenRegistrar.getStandardizedTokenId(wallet.address, salt); + const tokenAddress = await standardizedTokenRegistrar.getStandardizedTokenAddress(wallet.address, salt); + let params = defaultAbiCoder.encode(['bytes', 'address'], [standardizedTokenRegistrar.address, tokenAddress]); + const tokenManager = new Contract(await service.getTokenManagerAddress(tokenId), ITokenManager.abi, wallet); + const token = new Contract(tokenAddress, IERC20.abi, wallet); + await expect(standardizedTokenRegistrar.deployStandardizedToken(salt, name, symbol, decimals, mintAmount, wallet.address)) + .to.emit(service, 'StandardizedTokenDeployed') + .withArgs(tokenId, wallet.address, name, symbol, decimals, mintAmount, standardizedTokenRegistrar.address) + .and.to.emit(service, 'TokenManagerDeployed') + .withArgs(tokenId, MINT_BURN, params) + .and.to.emit(token, 'Transfer') + .withArgs(standardizedTokenRegistrar.address, wallet.address, mintAmount) + .and.to.emit(tokenManager, 'RolesAdded') + .withArgs(wallet.address, 1 << OPERATOR_ROLE) + .and.to.emit(tokenManager, 'RolesRemoved') + .withArgs(standardizedTokenRegistrar.address, 1 << OPERATOR_ROLE); + + 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, + wallet.address.toLowerCase(), + '0x', + mintAmount, + wallet.address.toLowerCase(), + ], + ); + + await expect( + standardizedTokenRegistrar.deployRemoteStandarizedToken( + salt, + wallet.address, + wallet.address, + mintAmount, + destinationChain, + gasValue, + { + value: gasValue, + }, + ), + ) + .to.emit(service, 'RemoteStandardizedTokenAndManagerDeploymentInitialized') + .withArgs( + tokenId, + name, + symbol, + decimals, + wallet.address.toLowerCase(), + '0x', + mintAmount, + wallet.address.toLowerCase(), + destinationChain, + gasValue, + ) + .and.to.emit(gasService, 'NativeGasPaidForContractCall') + .withArgs(service.address, destinationChain, service.address.toLowerCase(), keccak256(payload), gasValue, wallet.address) + .and.to.emit(gateway, 'ContractCall') + .withArgs(service.address, destinationChain, service.address.toLowerCase(), keccak256(payload), payload); + }); + + it('Should initiate a remote standardized token deployment without the same distributor', async () => { + const gasValue = 1234; + + const salt = keccak256('0x1245'); + tokenId = await standardizedTokenRegistrar.getStandardizedTokenId(wallet.address, salt); + const tokenAddress = await standardizedTokenRegistrar.getStandardizedTokenAddress(wallet.address, salt); + let params = defaultAbiCoder.encode(['bytes', 'address'], [standardizedTokenRegistrar.address, tokenAddress]); + const tokenManager = new Contract(await service.getTokenManagerAddress(tokenId), ITokenManager.abi, wallet); + const token = new Contract(tokenAddress, IERC20.abi, wallet); + await expect(standardizedTokenRegistrar.deployStandardizedToken(salt, name, symbol, decimals, mintAmount, wallet.address)) + .to.emit(service, 'StandardizedTokenDeployed') + .withArgs(tokenId, wallet.address, name, symbol, decimals, mintAmount, standardizedTokenRegistrar.address) + .and.to.emit(service, 'TokenManagerDeployed') + .withArgs(tokenId, MINT_BURN, params) + .and.to.emit(token, 'Transfer') + .withArgs(standardizedTokenRegistrar.address, wallet.address, mintAmount) + .and.to.emit(tokenManager, 'RolesAdded') + .withArgs(wallet.address, 1 << OPERATOR_ROLE) + .and.to.emit(tokenManager, 'RolesRemoved') + .withArgs(standardizedTokenRegistrar.address, 1 << OPERATOR_ROLE); + + 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, + wallet.address.toLowerCase(), + ], + ); + + await expect( + standardizedTokenRegistrar.deployRemoteStandarizedToken(salt, AddressZero, wallet.address, 0, destinationChain, gasValue, { + value: gasValue, + }), + ) + .to.emit(service, 'RemoteStandardizedTokenAndManagerDeploymentInitialized') + .withArgs(tokenId, name, symbol, decimals, '0x', '0x', 0, wallet.address.toLowerCase(), destinationChain, gasValue) + .and.to.emit(gasService, 'NativeGasPaidForContractCall') + .withArgs(service.address, destinationChain, service.address.toLowerCase(), keccak256(payload), gasValue, wallet.address) + .and.to.emit(gateway, 'ContractCall') + .withArgs(service.address, destinationChain, service.address.toLowerCase(), keccak256(payload), payload); + }); + + it('Should fail initiate a remote standardized token deployment without the same distributor with a mintAmount', async () => { + const gasValue = 1234; + const mintAmount = 5678; + + const salt = keccak256('0x124567'); + tokenId = await standardizedTokenRegistrar.getStandardizedTokenId(wallet.address, salt); + const tokenAddress = await standardizedTokenRegistrar.getStandardizedTokenAddress(wallet.address, salt); + let params = defaultAbiCoder.encode(['bytes', 'address'], [standardizedTokenRegistrar.address, tokenAddress]); + const tokenManager = new Contract(await service.getTokenManagerAddress(tokenId), ITokenManager.abi, wallet); + const token = new Contract(tokenAddress, IERC20.abi, wallet); + await expect(standardizedTokenRegistrar.deployStandardizedToken(salt, name, symbol, decimals, mintAmount, wallet.address)) + .to.emit(service, 'StandardizedTokenDeployed') + .withArgs(tokenId, wallet.address, name, symbol, decimals, mintAmount, standardizedTokenRegistrar.address) + .and.to.emit(service, 'TokenManagerDeployed') + .withArgs(tokenId, MINT_BURN, params) + .and.to.emit(token, 'Transfer') + .withArgs(standardizedTokenRegistrar.address, wallet.address, mintAmount) + .and.to.emit(tokenManager, 'RolesAdded') + .withArgs(wallet.address, 1 << OPERATOR_ROLE) + .and.to.emit(tokenManager, 'RolesRemoved') + .withArgs(standardizedTokenRegistrar.address, 1 << OPERATOR_ROLE); + + params = defaultAbiCoder.encode(['bytes', 'address'], ['0x', token.address]); + + await expect( + standardizedTokenRegistrar.deployRemoteStandarizedToken( + salt, + AddressZero, + wallet.address, + mintAmount, + destinationChain, + gasValue, + { + value: gasValue, + }, + ), + ).to.be.revertedWithCustomError(standardizedTokenRegistrar, 'NonZeroMintAmount'); + }); + }); +});