LayerZero Hook and ISM (#3102)

### Description
- Implements LayerZero V1 and V2 hook with V2 ISM.
- V2 ISM is backwards compatible i.e., V1 hook (which uses V1 endpoint
to send) can send to V2 ISM (which uses V2 endpoint to receive). See
[here](https://docs.layerzero.network/explore/migration#configuring-ultralightnode301)
for configuration.
- V2 uses `AbstractsMessageIdAuthorized*`. In. other words, hook passes
messageId through LayerZero, which stores into ISM to be used when
relayer calls `verify()` .
- Includes unit test for both V1 and V2 hook and ISM. 
   - V1 uses official LayerZero endpoint mock.

### Drive-by changes

<!--
Are there any minor or drive-by changes also included?
-->

### Related issues
- Implements #2853

### Backward compatibility
Yes

### Testing
Manual/Unit Tests
pull/3426/head
Lee 8 months ago committed by GitHub
parent b379336b91
commit ae0990a0b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 118
      solidity/contracts/hooks/layer-zero/LayerZeroV1Hook.sol
  2. 135
      solidity/contracts/hooks/layer-zero/LayerZeroV2Hook.sol
  3. 3
      solidity/contracts/interfaces/hooks/IPostDispatchHook.sol
  4. 2
      solidity/contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol
  5. 114
      solidity/contracts/isms/hook/layer-zero/LayerZeroV2Ism.sol
  6. 15
      solidity/contracts/test/TestLayerZeroTreasury.sol
  7. 3
      solidity/foundry.toml
  8. 2
      solidity/package.json
  9. 1
      solidity/remappings.txt
  10. 181
      solidity/test/hooks/layerzero/LayerZeroV1Hook.t.sol
  11. 207
      solidity/test/hooks/layerzero/LayerZeroV2Hook.t.sol
  12. 162
      solidity/test/isms/layer-zero/LayerZeroV2Ism.t.sol
  13. 633
      yarn.lock

@ -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));
}
}

@ -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:];
}
}

@ -23,7 +23,8 @@ interface IPostDispatchHook {
FALLBACK_ROUTING,
ID_AUTH_ISM,
PAUSABLE,
PROTOCOL_FEE
PROTOCOL_FEE,
LAYER_ZERO_V1
}
/**

@ -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"

@ -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;
}
}

@ -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
}
}

@ -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

@ -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",

@ -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/

@ -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));
}
}

@ -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));
}
}

@ -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);
}
}

@ -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"

Loading…
Cancel
Save