diff --git a/solidity/contracts/hooks/layer-zero/LayerZeroV1Hook.sol b/solidity/contracts/hooks/layer-zero/LayerZeroV1Hook.sol new file mode 100644 index 0000000000..d4b3d17fbf --- /dev/null +++ b/solidity/contracts/hooks/layer-zero/LayerZeroV1Hook.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/*@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@ HYPERLANE @@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ +@@@@@@@@@ @@@@@@@@*/ +import {ILayerZeroEndpoint} from "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.sol"; +import {Message} from "../../libs/Message.sol"; +import {TypeCasts} from "../../libs/TypeCasts.sol"; +import {MailboxClient} from "../../client/MailboxClient.sol"; +import {Indexed} from "../../libs/Indexed.sol"; +import {IPostDispatchHook} from "../../interfaces/hooks/IPostDispatchHook.sol"; +import {AbstractPostDispatchHook} from "../libs/AbstractPostDispatchHook.sol"; +import {StandardHookMetadata} from "../libs/StandardHookMetadata.sol"; + +struct LayerZeroMetadata { + /// @dev the destination chain identifier + uint16 dstChainId; + /// @dev the user app address on this EVM chain. Contract address that calls Endpoint.send(). Used for LZ user app config lookup + address userApplication; + /// @dev if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address + address refundAddress; + /// @dev the custom message to send over LayerZero + bytes payload; + /// @dev the address on destination chain (in bytes). A 40 length byte with remote and local addresses concatenated. + bytes destination; + /// @dev parameters for the adapter service, e.g. send some dust native token to dstChain + bytes adapterParam; +} + +contract LayerZeroV1Hook is AbstractPostDispatchHook, MailboxClient { + using StandardHookMetadata for bytes; + using Message for bytes; + using TypeCasts for bytes32; + + ILayerZeroEndpoint public immutable lZEndpoint; + + constructor(address _mailbox, address _lZEndpoint) MailboxClient(_mailbox) { + lZEndpoint = ILayerZeroEndpoint(_lZEndpoint); + } + + // ============ External Functions ============ + + /// @inheritdoc IPostDispatchHook + function hookType() external pure override returns (uint8) { + return uint8(IPostDispatchHook.Types.LAYER_ZERO_V1); + } + + /// @inheritdoc AbstractPostDispatchHook + function _postDispatch( + bytes calldata metadata, + bytes calldata message + ) internal virtual override { + // ensure hook only dispatches messages that are dispatched by the mailbox + bytes32 id = message.id(); + require(_isLatestDispatched(id), "message not dispatched by mailbox"); + + bytes calldata lZMetadata = metadata.getCustomMetadata(); + LayerZeroMetadata memory layerZeroMetadata = parseLzMetadata( + lZMetadata + ); + lZEndpoint.send{value: msg.value}( + layerZeroMetadata.dstChainId, + layerZeroMetadata.destination, + layerZeroMetadata.payload, + payable(layerZeroMetadata.refundAddress), + address(0), // _zroPaymentAddress is hardcoded to addr(0) because zro tokens should not be directly accepted + layerZeroMetadata.adapterParam + ); + } + + /// @inheritdoc AbstractPostDispatchHook + function _quoteDispatch( + bytes calldata metadata, + bytes calldata + ) internal view virtual override returns (uint256 nativeFee) { + bytes calldata lZMetadata = metadata.getCustomMetadata(); + LayerZeroMetadata memory layerZeroMetadata = parseLzMetadata( + lZMetadata + ); + (nativeFee, ) = lZEndpoint.estimateFees( + layerZeroMetadata.dstChainId, + layerZeroMetadata.userApplication, + layerZeroMetadata.payload, + false, // _payInZRO is hardcoded to false because zro tokens should not be directly accepted + layerZeroMetadata.adapterParam + ); + } + + /** + * @notice Formats LayerZero metadata using default abi encoding + * @param layerZeroMetadata LayerZero specific metadata + * @return ABI encoded metadata + */ + function formatLzMetadata( + LayerZeroMetadata calldata layerZeroMetadata + ) public pure returns (bytes memory) { + return abi.encode(layerZeroMetadata); + } + + /** + * @notice Decodes LayerZero metadata. Should be used after formatLzMetadata() + * @param lZMetadata ABI encoded metadata + */ + function parseLzMetadata( + bytes calldata lZMetadata + ) public pure returns (LayerZeroMetadata memory parsedLayerZeroMetadata) { + (parsedLayerZeroMetadata) = abi.decode(lZMetadata, (LayerZeroMetadata)); + } +} diff --git a/solidity/contracts/hooks/layer-zero/LayerZeroV2Hook.sol b/solidity/contracts/hooks/layer-zero/LayerZeroV2Hook.sol new file mode 100644 index 0000000000..244fea5c76 --- /dev/null +++ b/solidity/contracts/hooks/layer-zero/LayerZeroV2Hook.sol @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/*@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@ HYPERLANE @@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ +@@@@@@@@@ @@@@@@@@*/ +import {MessagingParams, MessagingFee, ILayerZeroEndpointV2} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; +import {Message} from "../../libs/Message.sol"; +import {TypeCasts} from "../../libs/TypeCasts.sol"; +import {Indexed} from "../../libs/Indexed.sol"; +import {IPostDispatchHook} from "../../interfaces/hooks/IPostDispatchHook.sol"; +import {AbstractMessageIdAuthHook} from "../libs/AbstractMessageIdAuthHook.sol"; +import {StandardHookMetadata} from "../libs/StandardHookMetadata.sol"; + +struct LayerZeroV2Metadata { + /// @dev the endpoint Id. prev dstChainId + uint32 eid; + /// @dev if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address + address refundAddress; + /// @dev parameters for the adapter service, e.g. send some dust native token to dstChain. prev adapterParam + bytes options; +} + +contract LayerZeroV2Hook is AbstractMessageIdAuthHook { + using StandardHookMetadata for bytes; + using Message for bytes; + using TypeCasts for bytes32; + + ILayerZeroEndpointV2 public immutable lZEndpoint; + + /// @dev offset for Layer Zero metadata parsing + uint8 constant EID_OFFSET = 0; + uint8 constant REFUND_ADDRESS_OFFSET = 4; + uint8 constant OPTIONS_OFFSET = 24; + + constructor( + address _mailbox, + uint32 _destinationDomain, + bytes32 _ism, + address _lZEndpoint + ) AbstractMessageIdAuthHook(_mailbox, _destinationDomain, _ism) { + lZEndpoint = ILayerZeroEndpointV2(_lZEndpoint); + } + + // ============ External Functions ============ + + /// @inheritdoc AbstractMessageIdAuthHook + function _sendMessageId( + bytes calldata metadata, + bytes memory payload + ) internal override { + bytes calldata lZMetadata = metadata.getCustomMetadata(); + ( + uint32 eid, + address refundAddress, + bytes memory options + ) = parseLzMetadata(lZMetadata); + + // Build and send message + MessagingParams memory msgParams = MessagingParams( + eid, + ism, + payload, + options, + false // payInLzToken + ); + lZEndpoint.send{value: msg.value}(msgParams, refundAddress); + } + + /// @dev payInZRO is hardcoded to false because zro tokens should not be directly accepted + function _quoteDispatch( + bytes calldata metadata, + bytes calldata message + ) internal view virtual override returns (uint256) { + bytes calldata lZMetadata = metadata.getCustomMetadata(); + (uint32 eid, , bytes memory options) = parseLzMetadata(lZMetadata); + + // Build and quote message + MessagingParams memory msgParams = MessagingParams( + eid, + message.recipient(), + message.body(), + options, + false // payInLzToken + ); + MessagingFee memory msgFee = lZEndpoint.quote( + msgParams, + message.senderAddress() + ); + + return msgFee.nativeFee; + } + + /** + * @notice Formats LayerZero metadata using default abi encoding + * @param layerZeroMetadata LayerZero specific metadata + * @return ABI encoded metadata + */ + function formatLzMetadata( + LayerZeroV2Metadata calldata layerZeroMetadata + ) public pure returns (bytes memory) { + return + abi.encodePacked( + layerZeroMetadata.eid, + layerZeroMetadata.refundAddress, + layerZeroMetadata.options + ); + } + + /** + * @notice Decodes LayerZero metadata. Should be used after formatLzMetadata() + * @param lZMetadata ABI encoded metadata + */ + function parseLzMetadata( + bytes calldata lZMetadata + ) + public + pure + returns (uint32 eid, address refundAddress, bytes memory options) + { + eid = uint32(bytes4(lZMetadata[EID_OFFSET:REFUND_ADDRESS_OFFSET])); + refundAddress = address( + bytes20(lZMetadata[REFUND_ADDRESS_OFFSET:OPTIONS_OFFSET]) + ); + options = lZMetadata[OPTIONS_OFFSET:]; + } +} diff --git a/solidity/contracts/interfaces/hooks/IPostDispatchHook.sol b/solidity/contracts/interfaces/hooks/IPostDispatchHook.sol index 69a44c7bc1..5e362afbbe 100644 --- a/solidity/contracts/interfaces/hooks/IPostDispatchHook.sol +++ b/solidity/contracts/interfaces/hooks/IPostDispatchHook.sol @@ -23,7 +23,8 @@ interface IPostDispatchHook { FALLBACK_ROUTING, ID_AUTH_ISM, PAUSABLE, - PROTOCOL_FEE + PROTOCOL_FEE, + LAYER_ZERO_V1 } /** diff --git a/solidity/contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol b/solidity/contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol index 2f9caf8a3f..519d4803bc 100644 --- a/solidity/contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol +++ b/solidity/contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol @@ -99,7 +99,7 @@ abstract contract AbstractMessageIdAuthorizedIsm is * @dev Only callable by the authorized hook. * @param messageId Hyperlane Id of the message. */ - function verifyMessageId(bytes32 messageId) external payable virtual { + function verifyMessageId(bytes32 messageId) public payable virtual { require( _isAuthorized(), "AbstractMessageIdAuthorizedIsm: sender is not the hook" diff --git a/solidity/contracts/isms/hook/layer-zero/LayerZeroV2Ism.sol b/solidity/contracts/isms/hook/layer-zero/LayerZeroV2Ism.sol new file mode 100644 index 0000000000..d7f8c7d7dc --- /dev/null +++ b/solidity/contracts/isms/hook/layer-zero/LayerZeroV2Ism.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.0; + +/*@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@ HYPERLANE @@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ + @@@@@@@@@ @@@@@@@@@ +@@@@@@@@@ @@@@@@@@*/ + +// ============ Internal Imports ============ + +import {IInterchainSecurityModule} from "../../../interfaces/IInterchainSecurityModule.sol"; +import {Message} from "../../../libs/Message.sol"; +import {TypeCasts} from "../../../libs/TypeCasts.sol"; +import {AbstractMessageIdAuthorizedIsm} from "../AbstractMessageIdAuthorizedIsm.sol"; + +// ============ External Imports ============ +import {Origin} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; + +/** + * @title LayerZeroV2Ism + * @notice Uses LayerZero V2 deliver and verify a messages Id + */ +contract LayerZeroV2Ism is AbstractMessageIdAuthorizedIsm { + using Message for bytes; + using TypeCasts for bytes32; + + // Layerzero endpoint address + address public immutable endpoint; + + // ============ Constants ============ + + uint8 public constant moduleType = + uint8(IInterchainSecurityModule.Types.NULL); + + // @dev the offset of msg.data where the function parameters (as bytes) begins. 4 bytes is always used when encoding the function selector + uint8 constant FUNC_SELECTOR_OFFSET = 4; + + // @dev the offset of msg.data where Origin.sender begins. 32 is always used since calldata comes in 32 bytes. + uint8 constant ORIGIN_SENDER_OFFSET = FUNC_SELECTOR_OFFSET + 32; + + // ============ Constructor ============ + constructor(address _endpoint) { + require( + _endpoint != address(0), + "LayerZeroV2Ism: invalid authorized endpoint" + ); + endpoint = _endpoint; + } + + /** + * @notice Entry point for receiving msg/packet from the LayerZero endpoint. + * @param _lzMessage The payload of the received message. + * @dev Authorization verifcation is done within verifyMessageId() -> _isAuthorized() + */ + function lzReceive( + Origin calldata, + bytes32, + bytes calldata _lzMessage, + address, + bytes calldata + ) external payable { + verifyMessageId(_messageId(_lzMessage)); + } + + // ============ Internal function ============ + + /** + * @notice Slices the messageId from the message delivered from LayerZeroV2Hook + * @dev message is created as abi.encodeCall(AbstractMessageIdAuthorizedIsm.verifyMessageId, id) + * @dev _message will be 36 bytes (4 bytes for function selector, and 32 bytes for messageId) + */ + function _messageId( + bytes calldata _message + ) internal pure returns (bytes32) { + return bytes32(_message[FUNC_SELECTOR_OFFSET:]); + } + + /** + * @notice Validates criterias to verify a message + * @dev this is called by AbstractMessageIdAuthorizedIsm.verifyMessageId + * @dev parses msg.value to get parameters from lzReceive() + */ + function _isAuthorized() internal view override returns (bool) { + require(_isAuthorizedHook(), "LayerZeroV2Ism: hook is not authorized"); + + require( + _isAuthorizedEndPoint(), + "LayerZeroV2Ism: endpoint is not authorized" + ); + + return true; + } + + /** + * @notice check if origin.sender is the authorized hook + */ + function _isAuthorizedHook() internal view returns (bool) { + return bytes32(msg.data[ORIGIN_SENDER_OFFSET:]) == authorizedHook; + } + + /** + * @notice check if LayerZero endpoint is authorized + */ + function _isAuthorizedEndPoint() internal view returns (bool) { + return msg.sender == endpoint; + } +} diff --git a/solidity/contracts/test/TestLayerZeroTreasury.sol b/solidity/contracts/test/TestLayerZeroTreasury.sol new file mode 100644 index 0000000000..fd8e25a051 --- /dev/null +++ b/solidity/contracts/test/TestLayerZeroTreasury.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity ^0.8.0; + +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +contract LayerZeroTreasuryMock is Ownable { + function withdraw() external onlyOwner { + //withdraw + } + + function withdrawAlt() external onlyOwner { + //withdraw token + } +} diff --git a/solidity/foundry.toml b/solidity/foundry.toml index 75766fc7d7..5f3db3949e 100644 --- a/solidity/foundry.toml +++ b/solidity/foundry.toml @@ -5,7 +5,8 @@ libs = ['node_modules', 'lib'] test = 'test' cache_path = 'forge-cache' allow_paths = ["../node_modules"] -solc = '0.8.19' +solc_version = '0.8.22' +evm_version= 'paris' optimizer = true optimizer_runs = 999_999 diff --git a/solidity/package.json b/solidity/package.json index 08d6f3d1bc..5050d3969b 100644 --- a/solidity/package.json +++ b/solidity/package.json @@ -5,10 +5,12 @@ "dependencies": { "@eth-optimism/contracts": "^0.6.0", "@hyperlane-xyz/utils": "3.8.0", + "@layerzerolabs/lz-evm-oapp-v2": "2.0.2", "@openzeppelin/contracts": "^4.9.3", "@openzeppelin/contracts-upgradeable": "^v4.9.3" }, "devDependencies": { + "@layerzerolabs/solidity-examples": "^1.1.0", "@nomiclabs/hardhat-ethers": "^2.2.1", "@nomiclabs/hardhat-waffle": "^2.0.6", "@typechain/ethers-v5": "^10.0.0", diff --git a/solidity/remappings.txt b/solidity/remappings.txt index e079b9c53f..1492dd8d72 100644 --- a/solidity/remappings.txt +++ b/solidity/remappings.txt @@ -1,4 +1,5 @@ @openzeppelin=../node_modules/@openzeppelin +@layerzerolabs=../node_modules/@layerzerolabs @eth-optimism=../node_modules/@eth-optimism ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ diff --git a/solidity/test/hooks/layerzero/LayerZeroV1Hook.t.sol b/solidity/test/hooks/layerzero/LayerZeroV1Hook.t.sol new file mode 100644 index 0000000000..a99ec9a5ec --- /dev/null +++ b/solidity/test/hooks/layerzero/LayerZeroV1Hook.t.sol @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.13; + +import {Test} from "forge-std/Test.sol"; +import {LZEndpointMock} from "@layerzerolabs/solidity-examples/contracts/lzApp/mocks/LZEndpointMock.sol"; +import {OmniCounter} from "@layerzerolabs/solidity-examples/contracts/examples/OmniCounter.sol"; +import {TypeCasts} from "../../../contracts/libs/TypeCasts.sol"; +import {StandardHookMetadata} from "../../../contracts/hooks/libs/StandardHookMetadata.sol"; +import {TestMailbox} from "../../../contracts/test/TestMailbox.sol"; +import {TestPostDispatchHook} from "../../../contracts/test/TestPostDispatchHook.sol"; +import {LayerZeroV1Hook, LayerZeroMetadata} from "../../../contracts/hooks/layer-zero/LayerZeroV1Hook.sol"; +import {IPostDispatchHook} from "../../../contracts/interfaces/hooks/IPostDispatchHook.sol"; + +import "forge-std/console.sol"; + +contract LayerZeroV1HookTest is Test { + using TypeCasts for address; + + OmniCounter crossChainCounterApp; + LZEndpointMock lZEndpointMock; + TestMailbox public mailbox; + TestPostDispatchHook requiredHook; + LayerZeroV1Hook hook; + address alice = makeAddr("alice"); + + function setUp() public { + lZEndpointMock = new LZEndpointMock(uint16(block.chainid)); + crossChainCounterApp = new OmniCounter(address(lZEndpointMock)); + requiredHook = new TestPostDispatchHook(); + mailbox = new TestMailbox(0); + hook = new LayerZeroV1Hook(address(mailbox), address(lZEndpointMock)); + + mailbox.setRequiredHook(address(requiredHook)); + + // Sets the endpoint destinations + lZEndpointMock.setDestLzEndpoint( + address(crossChainCounterApp), + address(lZEndpointMock) + ); + + // set hook as a trusted remote + crossChainCounterApp.setTrustedRemote( + uint16(block.chainid), + abi.encodePacked(address(hook), address(crossChainCounterApp)) + ); + } + + function testLzV1Hook_ParseLzMetadata_returnsCorrectData() public { + // format Lz metadata + uint16 dstChainId = uint16(block.chainid); + address userApplication = address(crossChainCounterApp); + address refundAddress = alice; + bytes memory payload = "Hello World!"; + bytes memory destination = abi.encodePacked( + userApplication, + address(lZEndpointMock) + ); // remoteAndLocalAddresses + bytes memory adapterParam = ""; + LayerZeroMetadata memory layerZeroMetadata = LayerZeroMetadata( + dstChainId, + userApplication, + refundAddress, + payload, + destination, + adapterParam + ); + bytes memory formattedMetadata = hook.formatLzMetadata( + layerZeroMetadata + ); + + LayerZeroMetadata memory parsedLayerZeroMetadata = hook.parseLzMetadata( + formattedMetadata + ); + assertEq(parsedLayerZeroMetadata.dstChainId, dstChainId); + assertEq(parsedLayerZeroMetadata.userApplication, userApplication); + assertEq(parsedLayerZeroMetadata.refundAddress, refundAddress); + assertEq(parsedLayerZeroMetadata.payload, payload); + assertEq(parsedLayerZeroMetadata.destination, destination); + assertEq(parsedLayerZeroMetadata.adapterParam, adapterParam); + } + + function testLzV1Hook_QuoteDispatch_returnsFeeAmount() + public + returns (uint256 nativeFee, bytes memory metadata) + { + // Build metadata to include LZ-specific data + uint16 dstChainId = uint16(block.chainid); + address userApplication = address(crossChainCounterApp); + address refundAddress = alice; + bytes memory payload = "Hello World!"; + bytes memory destination = abi.encodePacked( + userApplication, + address(lZEndpointMock) + ); // remoteAndLocalAddresses + bytes memory adapterParam = ""; + LayerZeroMetadata memory layerZeroMetadata = LayerZeroMetadata( + dstChainId, + userApplication, + refundAddress, + payload, + destination, + adapterParam + ); + bytes memory formattedLzMetadata = hook.formatLzMetadata( + layerZeroMetadata + ); + metadata = StandardHookMetadata.formatMetadata( + 0, + 0, + refundAddress, + formattedLzMetadata + ); + bytes memory message = mailbox.buildOutboundMessage( + 0, + address(lZEndpointMock).addressToBytes32(), + payload + ); + nativeFee = hook.quoteDispatch(metadata, message); + + // It costs something + assertGt(nativeFee, 0); + } + + function testLzV1Hook_PostDispatch_executesCrossChain() public { + ( + uint256 nativeFee, + bytes memory metadata + ) = testLzV1Hook_QuoteDispatch_returnsFeeAmount(); + + // dispatch also executes L0 call to increment counter + assertEq(crossChainCounterApp.counter(), 0); + mailbox.dispatch{value: nativeFee}( + 0, + address(crossChainCounterApp).addressToBytes32(), + "Hello World!", + metadata, + hook + ); + assertEq(crossChainCounterApp.counter(), 1); + } + + function testLzV1Hook_PostDispatch_notEnoughFee() public { + ( + uint256 nativeFee, + bytes memory metadata + ) = testLzV1Hook_QuoteDispatch_returnsFeeAmount(); + + vm.expectRevert("LayerZeroMock: not enough native for fees"); + mailbox.dispatch{value: nativeFee - 1}( + 0, + address(crossChainCounterApp).addressToBytes32(), + "Hello World!", + metadata, + hook + ); + } + + function testLzV1Hook_PostDispatch_refundExtraFee() public { + ( + uint256 nativeFee, + bytes memory metadata + ) = testLzV1Hook_QuoteDispatch_returnsFeeAmount(); + + uint256 balanceBefore = address(alice).balance; + mailbox.dispatch{value: nativeFee + 1}( + 0, + address(crossChainCounterApp).addressToBytes32(), + "Hello World!", + metadata, + hook + ); + uint256 balanceAfter = address(alice).balance; + + assertEq(balanceAfter, balanceBefore + 1); + } + + // TODO test failed/retry + function testLzV1Hook_HookType() public { + assertEq(hook.hookType(), uint8(IPostDispatchHook.Types.LAYER_ZERO_V1)); + } +} diff --git a/solidity/test/hooks/layerzero/LayerZeroV2Hook.t.sol b/solidity/test/hooks/layerzero/LayerZeroV2Hook.t.sol new file mode 100644 index 0000000000..94225d2876 --- /dev/null +++ b/solidity/test/hooks/layerzero/LayerZeroV2Hook.t.sol @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.13; + +import {Test} from "forge-std/Test.sol"; +import {EndpointV2} from "@layerzerolabs/lz-evm-protocol-v2/contracts/EndpointV2.sol"; +import {Errors} from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Errors.sol"; +import {SimpleMessageLib} from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/SimpleMessageLib.sol"; +import {OmniCounter} from "@layerzerolabs/solidity-examples/contracts/examples/OmniCounter.sol"; +import {TypeCasts} from "../../../contracts/libs/TypeCasts.sol"; +import {StandardHookMetadata} from "../../../contracts/hooks/libs/StandardHookMetadata.sol"; +import {TestMailbox} from "../../../contracts/test/TestMailbox.sol"; +import {TestPostDispatchHook} from "../../../contracts/test/TestPostDispatchHook.sol"; +import {TestIsm} from "../../../contracts/test/TestIsm.sol"; +import {LayerZeroTreasuryMock} from "../../../contracts/test/TestLayerZeroTreasury.sol"; +import {LayerZeroV2Hook, LayerZeroV2Metadata} from "../../../contracts/hooks/layer-zero/LayerZeroV2Hook.sol"; +import {IPostDispatchHook} from "../../../contracts/interfaces/hooks/IPostDispatchHook.sol"; + +import "forge-std/console.sol"; + +contract LayerZeroV2HookTest is Test { + using TypeCasts for address; + + uint32 internal localEid; + uint32 internal remoteEid; + EndpointV2 lZEndpointV2; + SimpleMessageLib internal simpleMsgLib; + + OmniCounter crossChainCounterApp; + TestMailbox public mailbox; + TestPostDispatchHook requiredHook; + TestIsm ism; + LayerZeroV2Hook hook; + address alice = makeAddr("alice"); + uint8 constant HYPERLANE_DEST_DOMAIN = 1; + + function setUp() public { + // Set up LZ + localEid = 1; + remoteEid = 2; + (lZEndpointV2, simpleMsgLib) = setupEndpointWithSimpleMsgLib(localEid); + crossChainCounterApp = new OmniCounter(address(lZEndpointV2)); + setDefaultMsgLib(lZEndpointV2, address(simpleMsgLib), remoteEid); + + // Setup Hyperlane + requiredHook = new TestPostDispatchHook(); + mailbox = new TestMailbox(HYPERLANE_DEST_DOMAIN); + ism = new TestIsm(); + hook = new LayerZeroV2Hook( + address(mailbox), + HYPERLANE_DEST_DOMAIN, + address(ism).addressToBytes32(), + address(lZEndpointV2) + ); + + mailbox.setRequiredHook(address(requiredHook)); + } + + function setUpEndpoint(uint32 _eid) public returns (EndpointV2) { + return new EndpointV2(_eid, address(this)); + } + + function setupEndpointWithSimpleMsgLib( + uint32 _eid + ) public returns (EndpointV2, SimpleMessageLib) { + EndpointV2 e = setUpEndpoint(_eid); + + LayerZeroTreasuryMock treasuryMock = new LayerZeroTreasuryMock(); + SimpleMessageLib msgLib = new SimpleMessageLib( + address(e), + address(treasuryMock) + ); + + // register msg lib + e.registerLibrary(address(msgLib)); + + return (e, msgLib); + } + + function setDefaultMsgLib( + EndpointV2 _endpoint, + address _msglib, + uint32 _remoteEid + ) public { + _endpoint.setDefaultSendLibrary(_remoteEid, _msglib); + _endpoint.setDefaultReceiveLibrary(_remoteEid, _msglib, 0); + } + + function testLzV2Hook_ParseLzMetadata_returnsCorrectData() public { + // format Lz metadata + address refundAddress = alice; + bytes memory options = "options"; + LayerZeroV2Metadata memory layerZeroMetadata = LayerZeroV2Metadata( + remoteEid, + refundAddress, + options + ); + bytes memory formattedMetadata = hook.formatLzMetadata( + layerZeroMetadata + ); + + (uint32 eid, address _refundAddress, bytes memory _options) = hook + .parseLzMetadata(formattedMetadata); + assertEq(eid, remoteEid); + assertEq(_refundAddress, refundAddress); + assertEq(_options, options); + } + + function testLzV2Hook_QuoteDispatch_returnsFeeAmount() + public + returns (uint256 nativeFee, bytes memory metadata) + { + // Build metadata to include LZ-specific data + address refundAddress = alice; + bytes memory payload = "Hello World!"; + bytes memory options = "options"; + LayerZeroV2Metadata memory layerZeroV2Metadata = LayerZeroV2Metadata( + remoteEid, + refundAddress, + options + ); + bytes memory formattedLzMetadata = hook.formatLzMetadata( + layerZeroV2Metadata + ); + metadata = StandardHookMetadata.formatMetadata( + 0, + 0, + refundAddress, + formattedLzMetadata + ); + bytes memory message = mailbox.buildOutboundMessage( + HYPERLANE_DEST_DOMAIN, + address(lZEndpointV2).addressToBytes32(), + payload + ); + nativeFee = hook.quoteDispatch(metadata, message); + + // It costs something + assertGt(nativeFee, 0); + } + + function testLzV2Hook_PostDispatch_notEnoughFee(uint256 balance) public { + ( + uint256 nativeFee, + bytes memory metadata + ) = testLzV2Hook_QuoteDispatch_returnsFeeAmount(); + + vm.assume(balance < nativeFee - 1); + + vm.deal(address(this), balance); + vm.expectRevert( + abi.encodeWithSelector( + Errors.InsufficientFee.selector, + 100, + balance, + 0, + 0 + ) + ); + mailbox.dispatch{value: balance}( + HYPERLANE_DEST_DOMAIN, + address(crossChainCounterApp).addressToBytes32(), + "Hello World!", + metadata, + hook + ); + } + + function testLzV2Hook_PostDispatch_refundExtraFee(uint256 balance) public { + ( + uint256 nativeFee, + bytes memory metadata + ) = testLzV2Hook_QuoteDispatch_returnsFeeAmount(); + vm.assume(balance > nativeFee); + + uint256 extraValue = balance - nativeFee; + vm.deal(address(this), balance); + + mailbox.dispatch{value: balance}( + HYPERLANE_DEST_DOMAIN, + address(crossChainCounterApp).addressToBytes32(), + "Hello World!", + metadata, + hook + ); + assertEq(address(alice).balance, extraValue); + } + + function testLzV2Hook_PostDispatch_executesCrossChain() public { + ( + uint256 nativeFee, + bytes memory metadata + ) = testLzV2Hook_QuoteDispatch_returnsFeeAmount(); + + mailbox.dispatch{value: nativeFee}( + HYPERLANE_DEST_DOMAIN, + address(crossChainCounterApp).addressToBytes32(), + "Hello World!", + metadata, + hook + ); + } + + // TODO test failed/retry + function testLzV2Hook_HookType() public { + assertEq(hook.hookType(), uint8(IPostDispatchHook.Types.ID_AUTH_ISM)); + } +} diff --git a/solidity/test/isms/layer-zero/LayerZeroV2Ism.t.sol b/solidity/test/isms/layer-zero/LayerZeroV2Ism.t.sol new file mode 100644 index 0000000000..0d778a4d92 --- /dev/null +++ b/solidity/test/isms/layer-zero/LayerZeroV2Ism.t.sol @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.13; + +import {Test} from "forge-std/Test.sol"; +import {Origin} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; +import {TypeCasts} from "../../../contracts/libs/TypeCasts.sol"; +import {Message} from "../../../contracts/libs/Message.sol"; +import {LibBit} from "../../../contracts/libs/LibBit.sol"; +import {LayerZeroV2Ism} from "../../../contracts/isms/hook/layer-zero/LayerZeroV2Ism.sol"; +import {AbstractMessageIdAuthorizedIsm} from "../../../contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol"; + +contract LayerZeroV2IsmTest is Test { + using TypeCasts for address; + using Message for bytes; + using LibBit for uint256; + + LayerZeroV2Ism lZIsm; + address endpoint; + address hook; + + function _encodedFunctionCall( + bytes32 _messageId + ) internal pure returns (bytes memory) { + return + abi.encodeCall( + AbstractMessageIdAuthorizedIsm.verifyMessageId, + (_messageId) + ); + } + + function setUp() public { + endpoint = makeAddr("endpointAddr"); + hook = makeAddr("hook"); + lZIsm = new LayerZeroV2Ism(endpoint); + } + + function _makeLzParameters( + address _sender, + bytes32 _guid, + bytes memory _message, + address _executor, + bytes memory _extraData + ) + internal + pure + returns ( + Origin memory origin, + bytes32 guid, + bytes memory message, + address executor, + bytes memory extraData + ) + { + origin = Origin(1, _sender.addressToBytes32(), 1); + guid = _guid; + message = _message; + executor = _executor; + extraData = _extraData; + } + + function testLzV2Ism_lzReceive_RevertWhen_NotCalledByEndpoint( + address _endpoint + ) public { + vm.assume(_endpoint != address(0)); + vm.assume(_endpoint != endpoint); + lZIsm.setAuthorizedHook(hook.addressToBytes32()); + + vm.startPrank(_endpoint); + ( + Origin memory origin, + bytes32 guid, + bytes memory message, + address executor, + bytes memory extraData + ) = _makeLzParameters( + hook, + bytes32(""), + _encodedFunctionCall(bytes32("")), + makeAddr("executor"), + bytes("") + ); + + vm.expectRevert("LayerZeroV2Ism: endpoint is not authorized"); + lZIsm.lzReceive(origin, guid, message, executor, extraData); + vm.stopPrank(); + + // Set endpoint + vm.prank(endpoint); + lZIsm.lzReceive( + origin, + guid, + _encodedFunctionCall(bytes32("")), + executor, + extraData + ); + } + + function testLzV2Ism_lzReceive_RevertWhen_NotSentByHook( + address _hook + ) public { + vm.assume(_hook != address(0)); + + ( + Origin memory origin, + bytes32 guid, + bytes memory message, + address executor, + bytes memory extraData + ) = _makeLzParameters( + _hook, + bytes32(""), + _encodedFunctionCall(bytes32("")), + makeAddr("executor"), + bytes("") + ); + + vm.startPrank(endpoint); + vm.expectRevert("LayerZeroV2Ism: hook is not authorized"); + lZIsm.lzReceive(origin, guid, message, executor, extraData); + vm.stopPrank(); + + // Set hook + vm.startPrank(endpoint); + lZIsm.setAuthorizedHook(_hook.addressToBytes32()); + + lZIsm.lzReceive( + origin, + guid, + _encodedFunctionCall(bytes32("")), + executor, + extraData + ); + vm.stopPrank(); + } + + function testLzV2Ism_verifyMessageId_SetsCorrectMessageId( + bytes32 messageId + ) public { + lZIsm.setAuthorizedHook(hook.addressToBytes32()); + vm.startPrank(endpoint); + ( + Origin memory origin, + bytes32 guid, + bytes memory message, + address executor, + bytes memory extraData + ) = _makeLzParameters( + hook, + bytes32(""), + _encodedFunctionCall(messageId), + makeAddr("executor"), + bytes("") + ); + lZIsm.lzReceive(origin, guid, message, executor, extraData); + vm.stopPrank(); + + bool messageIdVerified = lZIsm.verifiedMessages(messageId).isBitSet( + lZIsm.VERIFIED_MASK_INDEX() + ); + assertTrue(messageIdVerified); + } +} diff --git a/yarn.lock b/yarn.lock index 4c242d4937..0ade4907b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -95,6 +95,17 @@ __metadata: languageName: node linkType: hard +"@aws-crypto/sha256-js@npm:1.2.2": + version: 1.2.2 + resolution: "@aws-crypto/sha256-js@npm:1.2.2" + dependencies: + "@aws-crypto/util": "npm:^1.2.2" + "@aws-sdk/types": "npm:^3.1.0" + tslib: "npm:^1.11.1" + checksum: 1d49239e1ef93d3c5fda0f5c12eda098b14eb334cb5f604404bc6e4eaf418df9831e45f91985acfb9545eebde7a30815815ce70ab107ed147e515bbab644e791 + languageName: node + linkType: hard + "@aws-crypto/sha256-js@npm:2.0.0": version: 2.0.0 resolution: "@aws-crypto/sha256-js@npm:2.0.0" @@ -126,6 +137,17 @@ __metadata: languageName: node linkType: hard +"@aws-crypto/util@npm:^1.2.2": + version: 1.2.2 + resolution: "@aws-crypto/util@npm:1.2.2" + dependencies: + "@aws-sdk/types": "npm:^3.1.0" + "@aws-sdk/util-utf8-browser": "npm:^3.0.0" + tslib: "npm:^1.11.1" + checksum: 55cc2bb7923d2242cd58138926a19323b6cb6381b9fcc73c6ed5d7071be29e735e6d964f868b22991772377e6e5e3dc1a8aa640e4150222b509b4f5067c4c659 + languageName: node + linkType: hard + "@aws-crypto/util@npm:^2.0.0, @aws-crypto/util@npm:^2.0.1": version: 2.0.1 resolution: "@aws-crypto/util@npm:2.0.1" @@ -3371,6 +3393,13 @@ __metadata: languageName: node linkType: hard +"@colors/colors@npm:1.5.0": + version: 1.5.0 + resolution: "@colors/colors@npm:1.5.0" + checksum: 9d226461c1e91e95f067be2bdc5e6f99cfe55a721f45afb44122e23e4b8602eeac4ff7325af6b5a369f36396ee1514d3809af3f57769066d80d83790d8e53339 + languageName: node + linkType: hard + "@confio/ics23@npm:^0.6.8": version: 0.6.8 resolution: "@confio/ics23@npm:0.6.8" @@ -3907,7 +3936,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/abi@npm:5.7.0, @ethersproject/abi@npm:^5.0.9, @ethersproject/abi@npm:^5.7.0": +"@ethersproject/abi@npm:5.7.0, @ethersproject/abi@npm:^5.0.9, @ethersproject/abi@npm:^5.4.0, @ethersproject/abi@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/abi@npm:5.7.0" dependencies: @@ -3971,7 +4000,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/abstract-signer@npm:5.7.0, @ethersproject/abstract-signer@npm:^5.7.0": +"@ethersproject/abstract-signer@npm:5.7.0, @ethersproject/abstract-signer@npm:^5.4.1, @ethersproject/abstract-signer@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/abstract-signer@npm:5.7.0" dependencies: @@ -3997,7 +4026,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/address@npm:5.7.0, @ethersproject/address@npm:^5.0.8, @ethersproject/address@npm:^5.7.0": +"@ethersproject/address@npm:5.7.0, @ethersproject/address@npm:^5.0.8, @ethersproject/address@npm:^5.4.0, @ethersproject/address@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/address@npm:5.7.0" dependencies: @@ -4051,7 +4080,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/bignumber@npm:5.7.0, @ethersproject/bignumber@npm:^5.1.1, @ethersproject/bignumber@npm:^5.7.0": +"@ethersproject/bignumber@npm:5.7.0, @ethersproject/bignumber@npm:^5.1.1, @ethersproject/bignumber@npm:^5.4.1, @ethersproject/bignumber@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/bignumber@npm:5.7.0" dependencies: @@ -4073,7 +4102,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/bytes@npm:5.7.0, @ethersproject/bytes@npm:^5.0.8, @ethersproject/bytes@npm:^5.7.0": +"@ethersproject/bytes@npm:5.7.0, @ethersproject/bytes@npm:^5.0.8, @ethersproject/bytes@npm:^5.4.0, @ethersproject/bytes@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/bytes@npm:5.7.0" dependencies: @@ -4091,7 +4120,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/constants@npm:5.7.0, @ethersproject/constants@npm:^5.7.0": +"@ethersproject/constants@npm:5.7.0, @ethersproject/constants@npm:^5.4.0, @ethersproject/constants@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/constants@npm:5.7.0" dependencies: @@ -4109,7 +4138,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/contracts@npm:5.7.0, @ethersproject/contracts@npm:^5.7.0": +"@ethersproject/contracts@npm:5.7.0, @ethersproject/contracts@npm:^5.4.1, @ethersproject/contracts@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/contracts@npm:5.7.0" dependencies: @@ -4317,7 +4346,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/providers@npm:5.7.2, @ethersproject/providers@npm:^5.7.0, @ethersproject/providers@npm:^5.7.1, @ethersproject/providers@npm:^5.7.2": +"@ethersproject/providers@npm:5.7.2, @ethersproject/providers@npm:^5.4.4, @ethersproject/providers@npm:^5.7.0, @ethersproject/providers@npm:^5.7.1, @ethersproject/providers@npm:^5.7.2": version: 5.7.2 resolution: "@ethersproject/providers@npm:5.7.2" dependencies: @@ -4414,7 +4443,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/solidity@npm:5.7.0, @ethersproject/solidity@npm:^5.7.0": +"@ethersproject/solidity@npm:5.7.0, @ethersproject/solidity@npm:^5.4.0, @ethersproject/solidity@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/solidity@npm:5.7.0" dependencies: @@ -4450,7 +4479,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/transactions@npm:5.7.0, @ethersproject/transactions@npm:^5.7.0": +"@ethersproject/transactions@npm:5.7.0, @ethersproject/transactions@npm:^5.4.0, @ethersproject/transactions@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/transactions@npm:5.7.0" dependencies: @@ -4495,7 +4524,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/wallet@npm:5.7.0": +"@ethersproject/wallet@npm:5.7.0, @ethersproject/wallet@npm:^5.4.0": version: 5.7.0 resolution: "@ethersproject/wallet@npm:5.7.0" dependencies: @@ -4763,6 +4792,8 @@ __metadata: dependencies: "@eth-optimism/contracts": "npm:^0.6.0" "@hyperlane-xyz/utils": "npm:3.8.0" + "@layerzerolabs/lz-evm-oapp-v2": "npm:2.0.2" + "@layerzerolabs/solidity-examples": "npm:^1.1.0" "@nomiclabs/hardhat-ethers": "npm:^2.2.1" "@nomiclabs/hardhat-waffle": "npm:^2.0.6" "@openzeppelin/contracts": "npm:^4.9.3" @@ -5500,6 +5531,72 @@ __metadata: languageName: node linkType: hard +"@layerzerolabs/lz-evm-messagelib-v2@npm:^2.0.2": + version: 2.0.6 + resolution: "@layerzerolabs/lz-evm-messagelib-v2@npm:2.0.6" + dependencies: + "@layerzerolabs/lz-evm-protocol-v2": "npm:^2.0.6" + checksum: d0f0875470dde34bc6c5d5c0c621066c29ade6910507b853f9bd780537df546bff5c60c8c52a461621efde65d6e457c65cc73200bf7bdc2cee8d774b7e15e424 + languageName: node + linkType: hard + +"@layerzerolabs/lz-evm-oapp-v2@npm:2.0.2": + version: 2.0.2 + resolution: "@layerzerolabs/lz-evm-oapp-v2@npm:2.0.2" + dependencies: + "@layerzerolabs/lz-evm-messagelib-v2": "npm:^2.0.2" + "@layerzerolabs/lz-evm-protocol-v2": "npm:^2.0.2" + "@layerzerolabs/lz-evm-v1-0.7": "npm:^2.0.2" + peerDependencies: + solidity-bytes-utils: ^0.8.0 + checksum: bc5a4bc5493f756931b150eefe6a6c31ffe8c691c418191d22eff044f8ca653043edc64dd746f30fc4b05f3230e667a6e3f5005ade7c324283bf8550bbaa32f5 + languageName: node + linkType: hard + +"@layerzerolabs/lz-evm-protocol-v2@npm:^2.0.2, @layerzerolabs/lz-evm-protocol-v2@npm:^2.0.6": + version: 2.0.6 + resolution: "@layerzerolabs/lz-evm-protocol-v2@npm:2.0.6" + checksum: 868797107856bc3da48f26f0851ca9f329293af1bc6d033d20ce907225bc9bf2f1d903c32a3a8612338e6ded6cab6f029150004ac540143cc413c1687b8de2cb + languageName: node + linkType: hard + +"@layerzerolabs/lz-evm-sdk-v1-0.7@npm:^1.5.14": + version: 1.5.16 + resolution: "@layerzerolabs/lz-evm-sdk-v1-0.7@npm:1.5.16" + dependencies: + "@openzeppelin/contracts": "npm:3.4.2-solc-0.7" + "@openzeppelin/contracts-upgradeable": "npm:3.4.2-solc-0.7" + checksum: 29b5dab860151a95da0e405085931a7b23de2e314dd6cd078067964f8e658a0221cbf2956467108483e8e75d820fd79e6f9e3d60043345a2726ebcb9cf1d492f + languageName: node + linkType: hard + +"@layerzerolabs/lz-evm-v1-0.7@npm:^2.0.2": + version: 2.0.6 + resolution: "@layerzerolabs/lz-evm-v1-0.7@npm:2.0.6" + checksum: 76fc1788cfe4b13f1d42f60e3cf3a2e7501c1c689a4cc4b3dcee38521945d165de0cbe8972592e0bb3405e85bb541dd69956959a6efb134be899022871ebdc17 + languageName: node + linkType: hard + +"@layerzerolabs/solidity-examples@npm:^1.1.0": + version: 1.1.0 + resolution: "@layerzerolabs/solidity-examples@npm:1.1.0" + dependencies: + "@layerzerolabs/lz-evm-sdk-v1-0.7": "npm:^1.5.14" + "@openzeppelin-3/contracts": "npm:@openzeppelin/contracts@^3.4.2-solc-0.7" + "@openzeppelin/contracts": "npm:^4.4.1" + "@openzeppelin/contracts-upgradeable": "npm:^4.6.0" + "@openzeppelin/hardhat-upgrades": "npm:^1.18.3" + dotenv: "npm:^10.0.0" + erc721a: "npm:^4.2.3" + hardhat: "npm:^2.8.0" + hardhat-contract-sizer: "npm:^2.1.1" + hardhat-deploy: "npm:^0.10.5" + hardhat-deploy-ethers: "npm:^0.3.0-beta.13" + hardhat-gas-reporter: "npm:^1.0.6" + checksum: 6f8d488f42041ee8605daa957019b041d076f80f489f1aab0f232c16f347e99177c75cf6d0f33bd207b33f2b19a9f838145aff4627d2dc5067f07af9e9379737 + languageName: node + linkType: hard + "@ledgerhq/connect-kit-loader@npm:^1.0.1": version: 1.1.8 resolution: "@ledgerhq/connect-kit-loader@npm:1.1.8" @@ -6331,6 +6428,27 @@ __metadata: languageName: node linkType: hard +"@openzeppelin-3/contracts@npm:@openzeppelin/contracts@^3.4.2-solc-0.7": + version: 3.4.2 + resolution: "@openzeppelin/contracts@npm:3.4.2" + checksum: e803e322bd111565e2de742c62f1a598c7c7dd7385c1c0fe3c06e2b4913e599024ad1d32e2693f199f5230af4d9b0eeefb389f32740006312895b962a4d937d4 + languageName: node + linkType: hard + +"@openzeppelin/contracts-upgradeable@npm:3.4.2-solc-0.7": + version: 3.4.2-solc-0.7 + resolution: "@openzeppelin/contracts-upgradeable@npm:3.4.2-solc-0.7" + checksum: 981fe98f2b602c615932bbf025b3cd9b3bbec2cde74660d8172e943aa221460dcf3aeb7ad17c4a34ff7a85c55ab1e9e71c3806a2b9d4eb83b1c9f4717732797d + languageName: node + linkType: hard + +"@openzeppelin/contracts-upgradeable@npm:^4.6.0": + version: 4.9.5 + resolution: "@openzeppelin/contracts-upgradeable@npm:4.9.5" + checksum: 9a0d137bff231b60ca30840aea225f9baf1d8bf5f229d21d64c67af3793fd381d9dae9b66536ea8c156e46354d8d5b1d4141d33434892ba989f056c972f9e731 + languageName: node + linkType: hard + "@openzeppelin/contracts-upgradeable@npm:^4.9.3, @openzeppelin/contracts-upgradeable@npm:^v4.9.3": version: 4.9.3 resolution: "@openzeppelin/contracts-upgradeable@npm:4.9.3" @@ -6338,6 +6456,20 @@ __metadata: languageName: node linkType: hard +"@openzeppelin/contracts@npm:3.4.2-solc-0.7": + version: 3.4.2-solc-0.7 + resolution: "@openzeppelin/contracts@npm:3.4.2-solc-0.7" + checksum: a21aa0a623f020cb32cd3c6b7903d806ec458b2a750feb86f5e3bcf0b7ae124d844b9d1c029f9e0707d6263b561f35a694bafc1b0bff30c3e95541124f8fd41c + languageName: node + linkType: hard + +"@openzeppelin/contracts@npm:^4.4.1": + version: 4.9.5 + resolution: "@openzeppelin/contracts@npm:4.9.5" + checksum: f221d91a7dd96f9187aa832f8a160d673feb2904711bd210fab56ccfd8b8351b8150b4f0bd247701f7d4adddceba83943c049c6da11d126e07164b9abff767e0 + languageName: node + linkType: hard + "@openzeppelin/contracts@npm:^4.9.3": version: 4.9.3 resolution: "@openzeppelin/contracts@npm:4.9.3" @@ -6345,6 +6477,74 @@ __metadata: languageName: node linkType: hard +"@openzeppelin/defender-base-client@npm:^1.46.0": + version: 1.54.1 + resolution: "@openzeppelin/defender-base-client@npm:1.54.1" + dependencies: + amazon-cognito-identity-js: "npm:^6.0.1" + async-retry: "npm:^1.3.3" + axios: "npm:^1.4.0" + lodash: "npm:^4.17.19" + node-fetch: "npm:^2.6.0" + checksum: 56a3cbba49820a8c68c22ae168a99a94790bda95cee52b4b880dd8adcf5656526c0a7903cc5a168164199d59e987484846fe468349872af0f65cc48b89087c90 + languageName: node + linkType: hard + +"@openzeppelin/hardhat-upgrades@npm:^1.18.3": + version: 1.28.0 + resolution: "@openzeppelin/hardhat-upgrades@npm:1.28.0" + dependencies: + "@openzeppelin/defender-base-client": "npm:^1.46.0" + "@openzeppelin/platform-deploy-client": "npm:^0.8.0" + "@openzeppelin/upgrades-core": "npm:^1.27.0" + chalk: "npm:^4.1.0" + debug: "npm:^4.1.1" + proper-lockfile: "npm:^4.1.1" + peerDependencies: + "@nomiclabs/hardhat-ethers": ^2.0.0 + "@nomiclabs/hardhat-etherscan": ^3.1.0 + ethers: ^5.0.5 + hardhat: ^2.0.2 + peerDependenciesMeta: + "@nomiclabs/harhdat-etherscan": + optional: true + bin: + migrate-oz-cli-project: dist/scripts/migrate-oz-cli-project.js + checksum: 4179635243bbc7786c46d65ac0848ac217669d8496383fca89806544778a5f23b38ebeceea341dda8b4547d4e8b4ba67f0138aff9e8fac51e2619d11b517db27 + languageName: node + linkType: hard + +"@openzeppelin/platform-deploy-client@npm:^0.8.0": + version: 0.8.0 + resolution: "@openzeppelin/platform-deploy-client@npm:0.8.0" + dependencies: + "@ethersproject/abi": "npm:^5.6.3" + "@openzeppelin/defender-base-client": "npm:^1.46.0" + axios: "npm:^0.21.2" + lodash: "npm:^4.17.19" + node-fetch: "npm:^2.6.0" + checksum: a5eb346929b9d0d3b4b245a6a910105906a396f092a1df193bb7bb4feb7910a08e3c990c02079a477d28f4b32e8e659468159382cc632034da58d87d5eccb624 + languageName: node + linkType: hard + +"@openzeppelin/upgrades-core@npm:^1.27.0": + version: 1.32.2 + resolution: "@openzeppelin/upgrades-core@npm:1.32.2" + dependencies: + cbor: "npm:^9.0.0" + chalk: "npm:^4.1.0" + compare-versions: "npm:^6.0.0" + debug: "npm:^4.1.1" + ethereumjs-util: "npm:^7.0.3" + minimist: "npm:^1.2.7" + proper-lockfile: "npm:^4.1.1" + solidity-ast: "npm:^0.4.51" + bin: + openzeppelin-upgrades-core: dist/cli/cli.js + checksum: 4c99aa23542c59c2df15625f328746d9afafd28b77d8fa034eb1c3729e3a221683772982f3e54bc7e027298dd425b87676a776159ca130a95d98c26afe92508c + languageName: node + linkType: hard + "@parcel/watcher-android-arm64@npm:2.4.0": version: 2.4.0 resolution: "@parcel/watcher-android-arm64@npm:2.4.0" @@ -7891,6 +8091,13 @@ __metadata: languageName: node linkType: hard +"@types/qs@npm:^6.9.7": + version: 6.9.11 + resolution: "@types/qs@npm:6.9.11" + checksum: 620ca1628bf3da65662c54ed6ebb120b18a3da477d0bfcc872b696685a9bb1893c3c92b53a1190a8f54d52eaddb6af8b2157755699ac83164604329935e8a7f2 + languageName: node + linkType: hard + "@types/react@npm:*": version: 18.2.57 resolution: "@types/react@npm:18.2.57" @@ -9005,6 +9212,19 @@ __metadata: languageName: node linkType: hard +"amazon-cognito-identity-js@npm:^6.0.1": + version: 6.3.8 + resolution: "amazon-cognito-identity-js@npm:6.3.8" + dependencies: + "@aws-crypto/sha256-js": "npm:1.2.2" + buffer: "npm:4.9.2" + fast-base64-decode: "npm:^1.0.0" + isomorphic-unfetch: "npm:^3.0.0" + js-cookie: "npm:^2.2.1" + checksum: 4738eb4b0af80d50e9fe0887a1394130dce030b603066bc44606854ef27158c0ea0df31eb49a5d0ddacce48265c120b6d65a6c817a58e9ff247cfe91cadbd3b6 + languageName: node + linkType: hard + "amdefine@npm:>=0.0.4": version: 1.0.1 resolution: "amdefine@npm:1.0.1" @@ -9256,6 +9476,19 @@ __metadata: languageName: node linkType: hard +"array.prototype.findlast@npm:^1.2.2": + version: 1.2.3 + resolution: "array.prototype.findlast@npm:1.2.3" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + es-shim-unscopables: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.1" + checksum: d615b5298b3c9bd2e59f4ffd7e2a35b99e03313ac5a035e8138ab32c3b8fcb5a770748f65c8a891e4e2a1c39f57cc091385a7454474f1fa0c1f2c20f4e2e5d32 + languageName: node + linkType: hard + "array.prototype.flat@npm:^1.2.3": version: 1.3.2 resolution: "array.prototype.flat@npm:1.3.2" @@ -9395,6 +9628,15 @@ __metadata: languageName: node linkType: hard +"async-retry@npm:^1.3.3": + version: 1.3.3 + resolution: "async-retry@npm:1.3.3" + dependencies: + retry: "npm:0.13.1" + checksum: 38a7152ff7265a9321ea214b9c69e8224ab1febbdec98efbbde6e562f17ff68405569b796b1c5271f354aef8783665d29953f051f68c1fc45306e61aec82fdc4 + languageName: node + linkType: hard + "async@npm:^2.6.4": version: 2.6.4 resolution: "async@npm:2.6.4" @@ -9479,7 +9721,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:^0.21.2": +"axios@npm:^0.21.1, axios@npm:^0.21.2": version: 0.21.4 resolution: "axios@npm:0.21.4" dependencies: @@ -9488,6 +9730,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.4.0": + version: 1.6.2 + resolution: "axios@npm:1.6.2" + dependencies: + follow-redirects: "npm:^1.15.0" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 612bc93f8f738a518e7c5f9de9cc782bcd36aac6bae279160ef6a10260378e21c1786520eab3336898e3d66e0839ebdf739f327fb6d0431baa4d3235703a7652 + languageName: node + linkType: hard + "babel-jest@npm:^29.7.0": version: 29.7.0 resolution: "babel-jest@npm:29.7.0" @@ -9580,7 +9833,7 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": +"base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 @@ -9964,6 +10217,17 @@ __metadata: languageName: node linkType: hard +"buffer@npm:4.9.2": + version: 4.9.2 + resolution: "buffer@npm:4.9.2" + dependencies: + base64-js: "npm:^1.0.2" + ieee754: "npm:^1.1.4" + isarray: "npm:^1.0.0" + checksum: 4852a455e167bc8ca580c3c585176bbe0931c9929aeb68f3e0b49adadcb4e513fd0922a43efdf67ddb2e8785bbe8254ae17f4b69038dd06329ee9e3283c8508f + languageName: node + linkType: hard + "buffer@npm:6.0.3, buffer@npm:^6.0.3, buffer@npm:~6.0.3": version: 6.0.3 resolution: "buffer@npm:6.0.3" @@ -10195,6 +10459,15 @@ __metadata: languageName: node linkType: hard +"cbor@npm:^9.0.0": + version: 9.0.1 + resolution: "cbor@npm:9.0.1" + dependencies: + nofilter: "npm:^3.1.0" + checksum: fa1bdf233b7d8b95b991c7d3861b6bf300b0d62fcebda34e4cca53605d32585021e80ee00b52378f492da011ebde6b21d704ac5117c2c6cce30de0b6419d2372 + languageName: node + linkType: hard + "chai@npm:^4.3.4, chai@npm:^4.3.6": version: 4.3.6 resolution: "chai@npm:4.3.6" @@ -10472,6 +10745,19 @@ __metadata: languageName: node linkType: hard +"cli-table3@npm:^0.6.0": + version: 0.6.3 + resolution: "cli-table3@npm:0.6.3" + dependencies: + "@colors/colors": "npm:1.5.0" + string-width: "npm:^4.2.0" + dependenciesMeta: + "@colors/colors": + optional: true + checksum: 8d82b75be7edc7febb1283dc49582a521536527cba80af62a2e4522a0ee39c252886a1a2f02d05ae9d753204dbcffeb3a40d1358ee10dccd7fe8d935cfad3f85 + languageName: node + linkType: hard + "cli-truncate@npm:^2.1.0": version: 2.1.0 resolution: "cli-truncate@npm:2.1.0" @@ -10756,6 +11042,13 @@ __metadata: languageName: node linkType: hard +"compare-versions@npm:^6.0.0": + version: 6.1.0 + resolution: "compare-versions@npm:6.1.0" + checksum: 20f349e7f8ad784704c68265f4e660e2abbe2c3d5c75793184fccb85f0c5c0263260e01fdd4488376f6b74b0f069e16c9684463f7316b075716fb1581eb36b77 + languageName: node + linkType: hard + "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" @@ -11668,7 +11961,7 @@ __metadata: languageName: node linkType: hard -"encode-utf8@npm:^1.0.3": +"encode-utf8@npm:^1.0.2, encode-utf8@npm:^1.0.3": version: 1.0.3 resolution: "encode-utf8@npm:1.0.3" checksum: 0204c37cda21bf19bb8f87f7ec6c89a23d43488c2ef1e5cfa40b64ee9568e63e15dc323fa7f50a491e2c6d33843a6b409f6de09afbf6cf371cb8da596cc64b44 @@ -11721,6 +12014,16 @@ __metadata: languageName: node linkType: hard +"enquirer@npm:^2.3.6": + version: 2.4.1 + resolution: "enquirer@npm:2.4.1" + dependencies: + ansi-colors: "npm:^4.1.1" + strip-ansi: "npm:^6.0.1" + checksum: b3726486cd98f0d458a851a03326a2a5dd4d84f37ff94ff2a2960c915e0fc865865da3b78f0877dc36ac5c1189069eca603e82ec63d5bc6b0dd9985bf6426d7a + languageName: node + linkType: hard + "entities@npm:2.2.0": version: 2.2.0 resolution: "entities@npm:2.2.0" @@ -11735,6 +12038,13 @@ __metadata: languageName: node linkType: hard +"erc721a@npm:^4.2.3": + version: 4.2.3 + resolution: "erc721a@npm:4.2.3" + checksum: afde64bfd323f0013576096ab321f6a690d83ced14217eae65761c00834f5ca6579d7cac057ee73ee7cd47bd49ee25dcd947023248f354ea8e85f3310188ea9b + languageName: node + linkType: hard + "err-code@npm:^2.0.2": version: 2.0.3 resolution: "err-code@npm:2.0.3" @@ -12378,7 +12688,7 @@ __metadata: languageName: node linkType: hard -"ethereumjs-util@npm:^7.1.0, ethereumjs-util@npm:^7.1.1, ethereumjs-util@npm:^7.1.2, ethereumjs-util@npm:^7.1.3, ethereumjs-util@npm:^7.1.4, ethereumjs-util@npm:^7.1.5": +"ethereumjs-util@npm:^7.0.3, ethereumjs-util@npm:^7.1.0, ethereumjs-util@npm:^7.1.1, ethereumjs-util@npm:^7.1.2, ethereumjs-util@npm:^7.1.3, ethereumjs-util@npm:^7.1.4, ethereumjs-util@npm:^7.1.5": version: 7.1.5 resolution: "ethereumjs-util@npm:7.1.5" dependencies: @@ -12699,6 +13009,13 @@ __metadata: languageName: node linkType: hard +"fast-base64-decode@npm:^1.0.0": + version: 1.0.0 + resolution: "fast-base64-decode@npm:1.0.0" + checksum: 4c59eb1775a7f132333f296c5082476fdcc8f58d023c42ed6d378d2e2da4c328c7a71562f271181a725dd17cdaa8f2805346cc330cdbad3b8e4b9751508bd0a3 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -12934,6 +13251,15 @@ __metadata: languageName: node linkType: hard +"fmix@npm:^0.1.0": + version: 0.1.0 + resolution: "fmix@npm:0.1.0" + dependencies: + imul: "npm:^1.0.0" + checksum: c465344d4f169eaf10d45c33949a1e7a633f09dba2ac7063ce8ae8be743df5979d708f7f24900163589f047f5194ac5fc2476177ce31175e8805adfa7b8fb7a4 + languageName: node + linkType: hard + "follow-redirects@npm:^1.12.1": version: 1.15.1 resolution: "follow-redirects@npm:1.15.1" @@ -12944,7 +13270,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.14.0": +"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.15.0": version: 1.15.3 resolution: "follow-redirects@npm:1.15.3" peerDependenciesMeta: @@ -13083,6 +13409,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^10.0.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 05ce2c3b59049bcb7b52001acd000e44b3c4af4ec1f8839f383ef41ec0048e3cfa7fd8a637b1bddfefad319145db89be91f4b7c1db2908205d38bf91e7d1d3b7 + languageName: node + linkType: hard + "fs-extra@npm:^4.0.2": version: 4.0.3 resolution: "fs-extra@npm:4.0.3" @@ -13776,7 +14113,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 @@ -13870,7 +14207,63 @@ __metadata: languageName: node linkType: hard -"hardhat-gas-reporter@npm:^1.0.9": +"hardhat-contract-sizer@npm:^2.1.1": + version: 2.10.0 + resolution: "hardhat-contract-sizer@npm:2.10.0" + dependencies: + chalk: "npm:^4.0.0" + cli-table3: "npm:^0.6.0" + strip-ansi: "npm:^6.0.0" + peerDependencies: + hardhat: ^2.0.0 + checksum: 2b3011fe5333c2f1dbcfa6c73dcb1c61da9e2e045775c24bb773fe5f3ac14e9923907fef0e61fc2897e82a61997ce74e73baadb7f69dfdeccc86ae878cf67792 + languageName: node + linkType: hard + +"hardhat-deploy-ethers@npm:^0.3.0-beta.13": + version: 0.3.0-beta.13 + resolution: "hardhat-deploy-ethers@npm:0.3.0-beta.13" + peerDependencies: + ethers: ^5.0.0 + hardhat: ^2.0.0 + checksum: 8443d013a8fbf364a9b72576383014d2429dfd64fa62bc7813bac89a28d686f8ac6c34a6a76a2536edd2b07a4197974b598b90d23b414b6aeeff422458ed0b20 + languageName: node + linkType: hard + +"hardhat-deploy@npm:^0.10.5": + version: 0.10.6 + resolution: "hardhat-deploy@npm:0.10.6" + dependencies: + "@ethersproject/abi": "npm:^5.4.0" + "@ethersproject/abstract-signer": "npm:^5.4.1" + "@ethersproject/address": "npm:^5.4.0" + "@ethersproject/bignumber": "npm:^5.4.1" + "@ethersproject/bytes": "npm:^5.4.0" + "@ethersproject/constants": "npm:^5.4.0" + "@ethersproject/contracts": "npm:^5.4.1" + "@ethersproject/providers": "npm:^5.4.4" + "@ethersproject/solidity": "npm:^5.4.0" + "@ethersproject/transactions": "npm:^5.4.0" + "@ethersproject/wallet": "npm:^5.4.0" + "@types/qs": "npm:^6.9.7" + axios: "npm:^0.21.1" + chalk: "npm:^4.1.2" + chokidar: "npm:^3.5.2" + debug: "npm:^4.3.2" + enquirer: "npm:^2.3.6" + form-data: "npm:^4.0.0" + fs-extra: "npm:^10.0.0" + match-all: "npm:^1.2.6" + murmur-128: "npm:^0.2.1" + qs: "npm:^6.9.4" + peerDependencies: + "@ethersproject/hardware-wallets": ^5.0.14 + hardhat: ^2.6.8 + checksum: d476543bbb0780cd79b7f55ee4542434e7a3bb115ac279728a235506a4ac72b787da50e7b0f1a78c5ca330b74b6a423b83c946f8a6a457c52ca8a661977fcbc2 + languageName: node + linkType: hard + +"hardhat-gas-reporter@npm:^1.0.6, hardhat-gas-reporter@npm:^1.0.9": version: 1.0.9 resolution: "hardhat-gas-reporter@npm:1.0.9" dependencies: @@ -13949,6 +14342,72 @@ __metadata: languageName: node linkType: hard +"hardhat@npm:^2.8.0": + version: 2.19.3 + resolution: "hardhat@npm:2.19.3" + dependencies: + "@ethersproject/abi": "npm:^5.1.2" + "@metamask/eth-sig-util": "npm:^4.0.0" + "@nomicfoundation/ethereumjs-block": "npm:5.0.2" + "@nomicfoundation/ethereumjs-blockchain": "npm:7.0.2" + "@nomicfoundation/ethereumjs-common": "npm:4.0.2" + "@nomicfoundation/ethereumjs-evm": "npm:2.0.2" + "@nomicfoundation/ethereumjs-rlp": "npm:5.0.2" + "@nomicfoundation/ethereumjs-statemanager": "npm:2.0.2" + "@nomicfoundation/ethereumjs-trie": "npm:6.0.2" + "@nomicfoundation/ethereumjs-tx": "npm:5.0.2" + "@nomicfoundation/ethereumjs-util": "npm:9.0.2" + "@nomicfoundation/ethereumjs-vm": "npm:7.0.2" + "@nomicfoundation/solidity-analyzer": "npm:^0.1.0" + "@sentry/node": "npm:^5.18.1" + "@types/bn.js": "npm:^5.1.0" + "@types/lru-cache": "npm:^5.1.0" + adm-zip: "npm:^0.4.16" + aggregate-error: "npm:^3.0.0" + ansi-escapes: "npm:^4.3.0" + chalk: "npm:^2.4.2" + chokidar: "npm:^3.4.0" + ci-info: "npm:^2.0.0" + debug: "npm:^4.1.1" + enquirer: "npm:^2.3.0" + env-paths: "npm:^2.2.0" + ethereum-cryptography: "npm:^1.0.3" + ethereumjs-abi: "npm:^0.6.8" + find-up: "npm:^2.1.0" + fp-ts: "npm:1.19.3" + fs-extra: "npm:^7.0.1" + glob: "npm:7.2.0" + immutable: "npm:^4.0.0-rc.12" + io-ts: "npm:1.10.4" + keccak: "npm:^3.0.2" + lodash: "npm:^4.17.11" + mnemonist: "npm:^0.38.0" + mocha: "npm:^10.0.0" + p-map: "npm:^4.0.0" + raw-body: "npm:^2.4.1" + resolve: "npm:1.17.0" + semver: "npm:^6.3.0" + solc: "npm:0.7.3" + source-map-support: "npm:^0.5.13" + stacktrace-parser: "npm:^0.1.10" + tsort: "npm:0.0.1" + undici: "npm:^5.14.0" + uuid: "npm:^8.3.2" + ws: "npm:^7.4.6" + peerDependencies: + ts-node: "*" + typescript: "*" + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + bin: + hardhat: internal/cli/bootstrap.js + checksum: df2eeecfdab8d481fb98c73fab3996f707a37f0d000fdda97f42f069922b45a3695bf4cbab7bba4ae2774cdefec46649a3f255b756b097e14666e59247d2a9d6 + languageName: node + linkType: hard + "has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": version: 1.0.2 resolution: "has-bigints@npm:1.0.2" @@ -14344,7 +14803,7 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.1.13, ieee754@npm:^1.2.1": +"ieee754@npm:^1.1.13, ieee754@npm:^1.1.4, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" checksum: d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 @@ -14415,6 +14874,13 @@ __metadata: languageName: node linkType: hard +"imul@npm:^1.0.0": + version: 1.0.1 + resolution: "imul@npm:1.0.1" + checksum: 6c2af3d5f09e2135e14d565a2c108412b825b221eb2c881f9130467f2adccf7ae201773ae8bcf1be169e2d090567a1fdfa9cf20d3b7da7b9cecb95b920ff3e52 + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -14972,6 +15438,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:^1.0.0, isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + languageName: node + linkType: hard + "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -14979,13 +15452,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -14993,6 +15459,16 @@ __metadata: languageName: node linkType: hard +"isomorphic-unfetch@npm:^3.0.0": + version: 3.1.0 + resolution: "isomorphic-unfetch@npm:3.1.0" + dependencies: + node-fetch: "npm:^2.6.1" + unfetch: "npm:^4.2.0" + checksum: 4e760d9a3f94b42c59fe5c6b53202469cecd864875dcac927668b1f43eb57698422a0086fadde47f7815752c4f4e30ecf1ce9a0eb09c44a871a2484dbc580b39 + languageName: node + linkType: hard + "isomorphic-ws@npm:^4.0.1": version: 4.0.1 resolution: "isomorphic-ws@npm:4.0.1" @@ -15570,6 +16046,13 @@ __metadata: languageName: node linkType: hard +"js-cookie@npm:^2.2.1": + version: 2.2.1 + resolution: "js-cookie@npm:2.2.1" + checksum: 4387f5f5691cb96ca9ff8852c589d3012b53f484fda68630a39e20cabc6c5b740f09225e23233ba56cd9de6ebe300a23d20b2c7315f10c309ad5a89fd8c4990b + languageName: node + linkType: hard + "js-sdsl@npm:^4.1.4": version: 4.4.1 resolution: "js-sdsl@npm:4.4.1" @@ -16587,6 +17070,13 @@ __metadata: languageName: node linkType: hard +"match-all@npm:^1.2.6": + version: 1.2.6 + resolution: "match-all@npm:1.2.6" + checksum: f7e21e80aa2074b0140dcad6198145a9c89044bc164ab3365e7a5302bd180744c75bce53626aeec0753422ffead130d4142b0cd136f9cfff0eedb3227265ee3e + languageName: node + linkType: hard + "mcl-wasm@npm:^0.7.1": version: 0.7.9 resolution: "mcl-wasm@npm:0.7.9" @@ -16923,6 +17413,13 @@ __metadata: languageName: node linkType: hard +"minimist@npm:^1.2.7": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f + languageName: node + linkType: hard + "minipass-collect@npm:^1.0.2": version: 1.0.2 resolution: "minipass-collect@npm:1.0.2" @@ -17309,6 +17806,17 @@ __metadata: languageName: node linkType: hard +"murmur-128@npm:^0.2.1": + version: 0.2.1 + resolution: "murmur-128@npm:0.2.1" + dependencies: + encode-utf8: "npm:^1.0.2" + fmix: "npm:^0.1.0" + imul: "npm:^1.0.0" + checksum: 0ec68c6d2176f1361699585ea54562ed3fe7a9260841cd58e39fdab2e2da5bc856ee9c9df3c5ae02d1cf9cd14432c24c8b70f80e64a69ab3b3484808539b5e83 + languageName: node + linkType: hard + "mute-stream@npm:^1.0.0": version: 1.0.0 resolution: "mute-stream@npm:1.0.0" @@ -17570,9 +18078,9 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.11": - version: 2.6.12 - resolution: "node-fetch@npm:2.6.12" +"node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" dependencies: whatwg-url: "npm:^5.0.0" peerDependencies: @@ -17580,13 +18088,13 @@ __metadata: peerDependenciesMeta: encoding: optional: true - checksum: 370ed4d906edad9709a81b54a0141d37d2973a27dc80c723d8ac14afcec6dc67bc6c70986a96992b64ec75d08159cc4b65ce6aa9063941168ea5ac73b24df9f8 + checksum: b24f8a3dc937f388192e59bcf9d0857d7b6940a2496f328381641cb616efccc9866e89ec43f2ec956bbd6c3d3ee05524ce77fe7b29ccd34692b3a16f237d6676 languageName: node linkType: hard -"node-fetch@npm:^2.6.12": - version: 2.7.0 - resolution: "node-fetch@npm:2.7.0" +"node-fetch@npm:^2.6.11": + version: 2.6.12 + resolution: "node-fetch@npm:2.6.12" dependencies: whatwg-url: "npm:^5.0.0" peerDependencies: @@ -17594,7 +18102,7 @@ __metadata: peerDependenciesMeta: encoding: optional: true - checksum: b24f8a3dc937f388192e59bcf9d0857d7b6940a2496f328381641cb616efccc9866e89ec43f2ec956bbd6c3d3ee05524ce77fe7b29ccd34692b3a16f237d6676 + checksum: 370ed4d906edad9709a81b54a0141d37d2973a27dc80c723d8ac14afcec6dc67bc6c70986a96992b64ec75d08159cc4b65ce6aa9063941168ea5ac73b24df9f8 languageName: node linkType: hard @@ -17717,6 +18225,13 @@ __metadata: languageName: node linkType: hard +"nofilter@npm:^3.1.0": + version: 3.1.0 + resolution: "nofilter@npm:3.1.0" + checksum: f63d87231dfda4b783db17d75b15aac948f78e65f4f1043096ef441147f6667ff74cd4b3f57ada5dbe240be282d3e9838558ac863a66cb04ef25fff7b2b4be4e + languageName: node + linkType: hard + "noop-logger@npm:^0.1.1": version: 0.1.1 resolution: "noop-logger@npm:0.1.1" @@ -18715,6 +19230,17 @@ __metadata: languageName: node linkType: hard +"proper-lockfile@npm:^4.1.1": + version: 4.1.2 + resolution: "proper-lockfile@npm:4.1.2" + dependencies: + graceful-fs: "npm:^4.2.4" + retry: "npm:^0.12.0" + signal-exit: "npm:^3.0.2" + checksum: 000a4875f543f591872b36ca94531af8a6463ddb0174f41c0b004d19e231d7445268b422ff1ea595e43d238655c702250cd3d27f408e7b9d97b56f1533ba26bf + languageName: node + linkType: hard + "proto-list@npm:~1.2.1": version: 1.2.4 resolution: "proto-list@npm:1.2.4" @@ -18763,6 +19289,13 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: f0bb4a87cfd18f77bc2fba23ae49c3b378fb35143af16cc478171c623eebe181678f09439707ad80081d340d1593cd54a33a0113f3ccb3f4bc9451488780ee23 + languageName: node + linkType: hard + "prr@npm:~1.0.1": version: 1.0.1 resolution: "prr@npm:1.0.1" @@ -18900,6 +19433,15 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.9.4": + version: 6.11.2 + resolution: "qs@npm:6.11.2" + dependencies: + side-channel: "npm:^1.0.4" + checksum: f2321d0796664d0f94e92447ccd3bdfd6b6f3a50b6b762aa79d7f5b1ea3a7a9f94063ba896b82bc2a877ed6a7426d4081e4f16568fdb04f0ee188cca9d8505b4 + languageName: node + linkType: hard + "qs@npm:~6.5.2": version: 6.5.3 resolution: "qs@npm:6.5.3" @@ -19588,6 +20130,13 @@ __metadata: languageName: node linkType: hard +"retry@npm:0.13.1": + version: 0.13.1 + resolution: "retry@npm:0.13.1" + checksum: 6125ec2e06d6e47e9201539c887defba4e47f63471db304c59e4b82fc63c8e89ca06a77e9d34939a9a42a76f00774b2f46c0d4a4cbb3e287268bd018ed69426d + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -20345,6 +20894,15 @@ __metadata: languageName: node linkType: hard +"solidity-ast@npm:^0.4.51": + version: 0.4.55 + resolution: "solidity-ast@npm:0.4.55" + dependencies: + array.prototype.findlast: "npm:^1.2.2" + checksum: fb9d5c358f8ca50f40b0f4568717e9a6c0b4bdade2bb711bea1d6d84c3f19e253550b5ba1be03da767c9cc3388b79649cadd86613d55ea0147fe7944fc6d0dae + languageName: node + linkType: hard + "solidity-comments-extractor@npm:^0.0.7": version: 0.0.7 resolution: "solidity-comments-extractor@npm:0.0.7" @@ -21846,6 +22404,13 @@ __metadata: languageName: node linkType: hard +"unfetch@npm:^4.2.0": + version: 4.2.0 + resolution: "unfetch@npm:4.2.0" + checksum: d4924178060b6828d858acef3ce2baea69acd3f3f9e2429fd503a0ed0d2b1ed0ee107786aceadfd167ce884fad12d22b5288eb865a3ea036979b8358b8555c9a + languageName: node + linkType: hard + "unique-filename@npm:^1.1.1": version: 1.1.1 resolution: "unique-filename@npm:1.1.1"