From 8f2c272c43b2fc3c014c569b81b2d519d5768177 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Tue, 28 Mar 2023 19:02:09 +0200 Subject: [PATCH 01/23] first draft of ERC721 properties --- contracts/ERC721/external/echidna.config.yaml | 7 + .../ERC721ExternalBasicProperties.sol | 143 +++++++++++++++++ .../ERC721ExternalBurnableProperties.sol | 75 +++++++++ .../ERC721ExternalMintableProperties.sol | 40 +++++ .../external/util/ERC721ExternalTestBase.sol | 16 ++ .../ERC721/external/util/IERC721Mock.sol | 10 ++ contracts/ERC721/internal/echidna.config.yaml | 6 + .../properties/ERC721BasicProperties.sol | 145 ++++++++++++++++++ .../properties/ERC721BurnableProperties.sol | 97 ++++++++++++ .../properties/ERC721MintableProperties.sol | 51 ++++++ .../ERC721/internal/util/ERC721TestBase.sol | 34 ++++ 11 files changed, 624 insertions(+) create mode 100644 contracts/ERC721/external/echidna.config.yaml create mode 100644 contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol create mode 100644 contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol create mode 100644 contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol create mode 100644 contracts/ERC721/external/util/ERC721ExternalTestBase.sol create mode 100644 contracts/ERC721/external/util/IERC721Mock.sol create mode 100644 contracts/ERC721/internal/echidna.config.yaml create mode 100644 contracts/ERC721/internal/properties/ERC721BasicProperties.sol create mode 100644 contracts/ERC721/internal/properties/ERC721BurnableProperties.sol create mode 100644 contracts/ERC721/internal/properties/ERC721MintableProperties.sol create mode 100644 contracts/ERC721/internal/util/ERC721TestBase.sol diff --git a/contracts/ERC721/external/echidna.config.yaml b/contracts/ERC721/external/echidna.config.yaml new file mode 100644 index 0000000..4603034 --- /dev/null +++ b/contracts/ERC721/external/echidna.config.yaml @@ -0,0 +1,7 @@ +coverage: true +multi-abi: true +corpusDir: "corpus" +testMode: assertion +testLimit: 100000 +deployer: "0x10000" +sender: ["0x10000", "0x20000", "0x30000"] \ No newline at end of file diff --git a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol new file mode 100644 index 0000000..8311a6e --- /dev/null +++ b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol @@ -0,0 +1,143 @@ +pragma solidity ^0.8.13; + +import "../util/ERC721ExternalTestBase.sol"; + +abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTestBase { + using Address for address; + + constructor() { + } + + //////////////////////////////////////// + // Properties + + // Querying the balance of address(0) should throw + function test_ERC721_external_balanceOfZeroAddressMustRevert() public virtual { + token.balanceOf(address(0)); + assertWithMsg(false, "address(0) balance query should have reverted"); + } + + // Querying the owner of an invalid token should throw + function test_ERC721_external_ownerOfInvalidTokenMustRevert() public virtual { + token.ownerOf(type(uint256).max); + assertWithMsg(false, "Invalid token owner query should have reverted"); + } + + // Approving an invalid token should throw + function test_ERC721_external_approvingInvalidTokenMustRevert() public virtual { + token.approve(address(0), type(uint256).max); + assertWithMsg(false, "Approving an invalid token should have reverted"); + } + + // transferFrom a token that the caller is not approved for should revert + function test_ERC721_external_transferFromNotApproved(address target) public virtual { + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = token.isApprovedForAll(msg.sender, address(this)); + address approved = token.getApproved(tokenId); + require(approved != address(this) && !isApproved); + + token.transferFrom(msg.sender, target, tokenId); + assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Transferred a token without being approved."); + } + + // transferFrom should reset approval for that token + function test_ERC721_external_transferFromResetApproval(address target) public virtual { + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = token.isApprovedForAll(msg.sender, address(this)); + address approved = token.getApproved(tokenId); + require(approved == address(this) || isApproved); + token.transferFrom(msg.sender, target, tokenId); + + approved = token.getApproved(tokenId); + assertWithMsg(approved == address(0), "Approval was not reset"); + } + + // transferFrom correctly updates owner + function test_ERC721_external_transferFromUpdatesOwner(address target) public virtual { + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = token.isApprovedForAll(msg.sender, address(this)); + address approved = token.getApproved(tokenId); + require(approved == address(this) || isApproved); + token.transferFrom(msg.sender, target, tokenId); + + assertWithMsg(token.ownerOf(tokenId) == target, "Token owner not updated"); + } + + function test_ERC721_external_transferFromZeroAddress(address target, uint256 tokenId) public virtual { + require(target != address(this)); + require(target != msg.sender); + token.transferFrom(address(0), target, tokenId); + + assertWithMsg(token.ownerOf(tokenId) != target, "Transfered from zero address"); + } + + // Transfers to the zero address should revert + function test_ERC721_external_transferToZeroAddress() public virtual { + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + + token.transferFrom(msg.sender, address(0), tokenId); + + assertWithMsg(token.ownerOf(tokenId) == address(0), "Transfer to zero address should have reverted"); + } + + // Transfers to self should not break accounting + function test_ERC721_external_transferFromSelf() public virtual { + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = token.isApprovedForAll(msg.sender, address(this)); + address approved = token.getApproved(tokenId); + require(approved == address(this) || isApproved); + + token.transferFrom(msg.sender, msg.sender, tokenId); + assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); + assertEq(token.balanceOf(msg.sender), selfBalance, "Self transfer breaks accounting"); + } + + // Transfer to self reset approval + function test_ERC721_external_transferFromSelfResetsApproval() public virtual { + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = token.isApprovedForAll(msg.sender, address(this)); + address approved = token.getApproved(tokenId); + require(approved == address(this) || isApproved); + + token.transferFrom(msg.sender, msg.sender, tokenId); + assertWithMsg(token.getApproved(tokenId) == address(0), "Self transfer does not reset approvals"); + } + + // safeTransferFrom reverts if receiver does not implement the callback + function test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver(address target) public virtual { + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = token.isApprovedForAll(msg.sender, address(this)); + address approved = token.getApproved(tokenId); + require(approved == address(this) || isApproved); + require(!target.isContract()); + + token.safeTransferFrom(msg.sender, target, tokenId); + assertWithMsg(false, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); + } + + // todo test_ERC721_external_setApprovalForAllWorksAsExpected + // todo safeTransferFrom checks + +} diff --git a/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol new file mode 100644 index 0000000..0d3e4f8 --- /dev/null +++ b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol @@ -0,0 +1,75 @@ +pragma solidity ^0.8.13; + +import "../util/ERC721ExternalTestBase.sol"; + +abstract contract CryticERC721ExternalBurnableProperties is CryticERC721ExternalTestBase { + using Address for address; + + constructor() { + } + + //////////////////////////////////////// + // Properties + + // The burn function should destroy tokens and reduce the total supply + function test_ERC721_external_burnReducesTotalSupply(uint256 tokenId) public virtual { + require(token.isMintableOrBurnable()); + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 oldTotalSupply = token.totalSupply(); + for(uint256 i; i < selfBalance; i++) { + uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + token.burn(tokenId); + } + + assertEq(oldTotalSupply - selfBalance, token.totalSupply(), "Incorrect supply update on burn"); + } + + // A burned token should not be transferrable + function test_ERC721_external_burnRevertOnTransfer(address target) public virtual { + require(token.isMintableOrBurnable()); + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + token.burn(tokenId); + token.safeTransferFrom(msg.sender, target, tokenId); + assertWithMsg(false, "Transferring a burned token didn't revert"); + } + + function test_ERC721_external_burnRevertOnApprove() public virtual { + require(token.isMintableOrBurnable()); + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + token.burn(tokenId); + token.approve(address(this), tokenId); + assertWithMsg(false, "Approving a burned token didn't revert"); + } + + function test_ERC721_external_burnRevertOnGetApproved() public virtual { + require(token.isMintableOrBurnable()); + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + token.burn(tokenId); + token.getApproved(tokenId); + assertWithMsg(false, "getApproved didn't revert for burned token"); + } + + function test_ERC721_external_burnRevertOnOwnerOf() public virtual { + require(token.isMintableOrBurnable()); + uint256 selfBalance = token.balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + token.burn(tokenId); + token.ownerOf(tokenId); + assertWithMsg(false, "ownerOf didn't revert for burned token"); + } + + // todo burned token cannot be minted again +} diff --git a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol new file mode 100644 index 0000000..f931190 --- /dev/null +++ b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol @@ -0,0 +1,40 @@ +pragma solidity ^0.8.13; + +import "../util/ERC721ExternalTestBase.sol"; + +abstract contract CryticERC721ExternalMintableProperties is CryticERC721ExternalTestBase { + using Address for address; + + constructor() { + } + + //////////////////////////////////////// + // Properties + // mint increases the total supply + function test_ERC721_external_mintIncreasesSupply(uint256 amount) public virtual { + require(token.isMintableOrBurnable()); + uint256 selfBalance = token.balanceOf(msg.sender); + uint256 oldTotalSupply = token.totalSupply(); + _customMint(amount); + + assertEq(oldTotalSupply + amount, token.totalSupply(), "Total supply was not correctly increased"); + assertEq(selfBalance + amount, token.balanceOf(msg.sender), "Receiver supply was not correctly increased"); + } + + // mint creates a fresh token + function test_ERC721_external_mintCreatesFreshToken(uint256 amount) public virtual { + require(token.isMintableOrBurnable()); + uint256 selfBalance = token.balanceOf(msg.sender); + uint256 endIndex = selfBalance + amount; + _customMint(amount); + + for(uint256 i = selfBalance; i < endIndex; i++) { + uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, i); + assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Token ID was not minted to receiver"); + } + assertEq(selfBalance + amount, token.balanceOf(msg.sender), "Receiver supply was not correctly increased"); + } + + // Wrappers + function _customMint(uint256 amount) internal virtual; +} diff --git a/contracts/ERC721/external/util/ERC721ExternalTestBase.sol b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol new file mode 100644 index 0000000..cfe4eb5 --- /dev/null +++ b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol @@ -0,0 +1,16 @@ +pragma solidity ^0.8.0; + +import "../../../util/PropertiesHelper.sol"; +import "./IERC721Mock.sol"; +import "../../../util/PropertiesConstants.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; + + +abstract contract CryticERC721ExternalTestBase is PropertiesAsserts, PropertiesConstants { + + IERC721Mock token; + + constructor() { + } + +} diff --git a/contracts/ERC721/external/util/IERC721Mock.sol b/contracts/ERC721/external/util/IERC721Mock.sol new file mode 100644 index 0000000..3b13957 --- /dev/null +++ b/contracts/ERC721/external/util/IERC721Mock.sol @@ -0,0 +1,10 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; + +interface IERC721Mock is IERC721, IERC721Enumerable { + function isMintableOrBurnable() external returns (bool); + + function burn(uint256 tokenId) external; +} \ No newline at end of file diff --git a/contracts/ERC721/internal/echidna.config.yaml b/contracts/ERC721/internal/echidna.config.yaml new file mode 100644 index 0000000..b5ab450 --- /dev/null +++ b/contracts/ERC721/internal/echidna.config.yaml @@ -0,0 +1,6 @@ +coverage: true +corpusDir: "corpus" +testMode: assertion +testLimit: 100000 +deployer: "0x10000" +sender: ["0x10000", "0x20000", "0x30000"] \ No newline at end of file diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol new file mode 100644 index 0000000..83f3c8a --- /dev/null +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -0,0 +1,145 @@ +pragma solidity ^0.8.13; + +import "../util/ERC721TestBase.sol"; + +abstract contract CryticERC721BasicProperties is CryticERC721Base { + using Address for address; + + constructor() { + } + + //////////////////////////////////////// + // Properties + + // Querying the balance of address(0) should throw + function test_ERC20_balanceOfZeroAddressMustRevert() public virtual { + balanceOf(address(0)); + assertWithMsg(false, "address(0) balance query should have reverted"); + } + + // Querying the owner of an invalid token should throw + function test_ERC721_ownerOfInvalidTokenMustRevert(uint256 tokenId) public virtual { + require(!_exists(tokenId)); + ownerOf(tokenId); + assertWithMsg(false, "Invalid token owner query should have reverted"); + } + + // Approving an invalid token should throw + function test_ERC721_approvingInvalidTokenMustRevert(uint256 tokenId) public virtual { + require(!_exists(tokenId)); + approve(address(0), tokenId); + assertWithMsg(false, "Approving an invalid token should have reverted"); + } + + // transferFrom a token that the caller is not approved for should revert + function test_ERC721_transferFromNotApproved(address target) public virtual { + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = isApprovedForAll(msg.sender, address(this)); + address approved = getApproved(tokenId); + require(approved != address(this) && !isApproved); + + transferFrom(msg.sender, target, tokenId); + assertWithMsg(ownerOf(tokenId) == msg.sender, "Transferred a token without being approved."); + } + + // transferFrom should reset approval for that token + function test_ERC721_transferFromResetApproval(address target) public virtual { + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = isApprovedForAll(msg.sender, address(this)); + address approved = getApproved(tokenId); + require(approved == address(this) || isApproved); + transferFrom(msg.sender, target, tokenId); + + approved = getApproved(tokenId); + assertWithMsg(approved == address(0), "Approval was not reset"); + } + + // transferFrom correctly updates owner + function test_ERC721_transferFromUpdatesOwner(address target) public virtual { + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = isApprovedForAll(msg.sender, address(this)); + address approved = getApproved(tokenId); + require(approved == address(this) || isApproved); + transferFrom(msg.sender, target, tokenId); + + assertWithMsg(ownerOf(tokenId) == target, "Token owner not updated"); + } + + function test_ERC721_transferFromZeroAddress(address target, uint256 tokenId) public virtual { + require(target != address(this)); + require(target != msg.sender); + transferFrom(address(0), target, tokenId); + + assertWithMsg(ownerOf(tokenId) != target, "Transfered from zero address"); + } + + // Transfers to the zero address should revert + function test_ERC721_transferToZeroAddress() public virtual { + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); + + transferFrom(msg.sender, address(0), tokenId); + + assertWithMsg(ownerOf(tokenId) == address(0), "Transfer to zero address should have reverted"); + } + + // Transfers to self should not break accounting + function test_ERC721_transferFromSelf() public virtual { + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = isApprovedForAll(msg.sender, address(this)); + address approved = getApproved(tokenId); + require(approved == address(this) || isApproved); + + transferFrom(msg.sender, msg.sender, tokenId); + assertWithMsg(ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); + assertEq(balanceOf(msg.sender), selfBalance, "Self transfer breaks accounting"); + } + + // Transfer to self reset approval + function test_ERC721_transferFromSelfResetsApproval() public virtual { + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = isApprovedForAll(msg.sender, address(this)); + address approved = getApproved(tokenId); + require(approved == address(this) || isApproved); + + transferFrom(msg.sender, msg.sender, tokenId); + assertWithMsg(getApproved(tokenId) == address(0), "Self transfer does not reset approvals"); + } + + // safeTransferFrom reverts if receiver does not implement the callback + function test_ERC721_safeTransferFromRevertsOnNoncontractReceiver(address target) public virtual { + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + require(target != address(this)); + require(target != msg.sender); + uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); + bool isApproved = isApprovedForAll(msg.sender, address(this)); + address approved = getApproved(tokenId); + require(approved == address(this) || isApproved); + require(!target.isContract()); + + safeTransferFrom(msg.sender, target, tokenId); + assertWithMsg(false, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); + } + + // todo test_ERC721_setApprovalForAllWorksAsExpected + // todo safeTransferFrom checks + +} diff --git a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol new file mode 100644 index 0000000..8752db0 --- /dev/null +++ b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol @@ -0,0 +1,97 @@ +pragma solidity ^0.8.13; + +import "../util/ERC721ExternalTestBase.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; + + +abstract contract CryticERC721BurnableProperties is CryticERC721ExternalTestBase, ERC721Burnable { + using Address for address; + + constructor() { + isMintableOrBurnable = true; + } + + //////////////////////////////////////// + // Properties + + // The burn function should destroy tokens and reduce the total supply + function test_ERC721_burnReducesTotalSupply(uint256 tokenId) public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 oldTotalSupply = totalSupply(); + for(uint256 i; i < selfBalance; i++) { + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); + burn(tokenId); + } + + assertEq(oldTotalSupply - selfBalance, totalSupply(), "Incorrect supply update on burn"); + } + + // A burned token should not be transferrable + function test_ERC721_burnRevertOnTransfer(address target) public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); + burn(tokenId); + safeTransferFrom(msg.sender, target, tokenId); + assertWithMsg(false, "Transferring a burned token didn't revert"); + } + + function test_ERC721_burnRevertOnApprove() public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); + burn(tokenId); + approve(address(this), tokenId); + assertWithMsg(false, "Approving a burned token didn't revert"); + } + + function test_ERC721_burnRevertOnGetApproved() public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); + burn(tokenId); + getApproved(tokenId); + assertWithMsg(false, "getApproved didn't revert for burned token"); + } + + function test_ERC721_burnRevertOnOwnerOf() public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); + burn(tokenId); + ownerOf(tokenId); + assertWithMsg(false, "ownerOf didn't revert for burned token"); + } + + + // todo burned token cannot be minted again + + // The following functions are overrides required by Solidity. + + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + override(ERC721, CryticERC721Base) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC721, CryticERC721Base) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} diff --git a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol new file mode 100644 index 0000000..015e692 --- /dev/null +++ b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol @@ -0,0 +1,51 @@ +pragma solidity ^0.8.13; + +import "../util/ERC721TestBase.sol"; + +abstract contract CryticERC721MintableProperties is CryticERC721Base { + using Address for address; + + constructor() { + isMintableOrBurnable = true; + } + + //////////////////////////////////////// + // Properties + // mint increases the total supply + function test_ERC721_mintIncreasesSupply(uint256 amount) public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + uint256 oldTotalSupply = totalSupply(); + _customMint(amount); + + assertEq(oldTotalSupply + amount, totalSupply(), "Total supply was not correctly increased"); + assertEq(selfBalance + amount, balanceOf(msg.sender), "Receiver supply was not correctly increased"); + } + + // mint creates a fresh token + function test_ERC721_mintCreatesFreshToken(uint256 amount) public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + uint256 endIndex = selfBalance + amount; + _customMint(amount); + + for(uint256 i = selfBalance; i < endIndex; i++) { + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, i); + assertWithMsg(ownerOf(tokenId) == msg.sender, "Token ID was not minted to receiver"); + } + assertEq(selfBalance + amount, balanceOf(msg.sender), "Receiver supply was not correctly increased"); + } + + // the total supply should never be larger than the max supply + function test_ERC721_totalSupplyShouldNotBeLargerThanMax() public virtual { + require(hasMaxSupply); + uint256 max = _customMaxSupply(); + uint256 total = totalSupply(); + + assertWithMsg(total <= max, "Total supply larger than max"); + } + + // Wrappers + function _customMint(uint256 amount) internal virtual; + function _customMaxSupply() internal virtual view returns (uint256); +} diff --git a/contracts/ERC721/internal/util/ERC721TestBase.sol b/contracts/ERC721/internal/util/ERC721TestBase.sol new file mode 100644 index 0000000..4b38d80 --- /dev/null +++ b/contracts/ERC721/internal/util/ERC721TestBase.sol @@ -0,0 +1,34 @@ +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "../../../util/PropertiesConstants.sol"; +import "../../../util/PropertiesHelper.sol"; + +abstract contract CryticERC721Base is ERC721, ERC721Enumerable, PropertiesAsserts, PropertiesConstants { + + // Is the contract allowed to change its total supply? + bool isMintableOrBurnable; + bool hasMaxSupply; + + constructor() { + } + + // The following functions are overrides required by Solidity. + + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + override(ERC721, ERC721Enumerable) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC721, ERC721Enumerable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} From 4e695e806e02665411ed4869092fcce6e22b556e Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Wed, 29 Mar 2023 16:10:43 +0200 Subject: [PATCH 02/23] chore: forge init --- .../ERC721/foundry/.github/workflows/test.yml | 34 +++++++++++++++++++ tests/ERC721/foundry/.gitignore | 14 ++++++++ tests/ERC721/foundry/foundry.toml | 6 ++++ tests/ERC721/foundry/script/Counter.s.sol | 12 +++++++ tests/ERC721/foundry/src/Counter.sol | 14 ++++++++ tests/ERC721/foundry/test/Counter.t.sol | 24 +++++++++++++ 6 files changed, 104 insertions(+) create mode 100644 tests/ERC721/foundry/.github/workflows/test.yml create mode 100644 tests/ERC721/foundry/.gitignore create mode 100644 tests/ERC721/foundry/foundry.toml create mode 100644 tests/ERC721/foundry/script/Counter.s.sol create mode 100644 tests/ERC721/foundry/src/Counter.sol create mode 100644 tests/ERC721/foundry/test/Counter.t.sol diff --git a/tests/ERC721/foundry/.github/workflows/test.yml b/tests/ERC721/foundry/.github/workflows/test.yml new file mode 100644 index 0000000..09880b1 --- /dev/null +++ b/tests/ERC721/foundry/.github/workflows/test.yml @@ -0,0 +1,34 @@ +name: test + +on: workflow_dispatch + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + strategy: + fail-fast: true + + name: Foundry project + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Run Forge build + run: | + forge --version + forge build --sizes + id: build + + - name: Run Forge tests + run: | + forge test -vvv + id: test diff --git a/tests/ERC721/foundry/.gitignore b/tests/ERC721/foundry/.gitignore new file mode 100644 index 0000000..85198aa --- /dev/null +++ b/tests/ERC721/foundry/.gitignore @@ -0,0 +1,14 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env diff --git a/tests/ERC721/foundry/foundry.toml b/tests/ERC721/foundry/foundry.toml new file mode 100644 index 0000000..e6810b2 --- /dev/null +++ b/tests/ERC721/foundry/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/tests/ERC721/foundry/script/Counter.s.sol b/tests/ERC721/foundry/script/Counter.s.sol new file mode 100644 index 0000000..0e546ab --- /dev/null +++ b/tests/ERC721/foundry/script/Counter.s.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Script.sol"; + +contract CounterScript is Script { + function setUp() public {} + + function run() public { + vm.broadcast(); + } +} diff --git a/tests/ERC721/foundry/src/Counter.sol b/tests/ERC721/foundry/src/Counter.sol new file mode 100644 index 0000000..aded799 --- /dev/null +++ b/tests/ERC721/foundry/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/tests/ERC721/foundry/test/Counter.t.sol b/tests/ERC721/foundry/test/Counter.t.sol new file mode 100644 index 0000000..30235e8 --- /dev/null +++ b/tests/ERC721/foundry/test/Counter.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; +import "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + function setUp() public { + counter = new Counter(); + counter.setNumber(0); + } + + function testIncrement() public { + counter.increment(); + assertEq(counter.number(), 1); + } + + function testSetNumber(uint256 x) public { + counter.setNumber(x); + assertEq(counter.number(), x); + } +} From 884e89d07f95e1af94847bf34088450a56021579 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Wed, 29 Mar 2023 16:43:15 +0200 Subject: [PATCH 03/23] ERC721 tests skeleton --- .gitmodules | 5 ++- remappings.txt | 6 +++ .../ERC721/foundry/.github/workflows/test.yml | 34 --------------- tests/ERC721/foundry/.gitignore | 14 ------- tests/ERC721/foundry/.gitmodules | 0 tests/ERC721/foundry/echidna-config-ext.yaml | 6 +++ tests/ERC721/foundry/echidna-config.yaml | 5 +++ tests/ERC721/foundry/foundry.toml | 2 +- tests/ERC721/foundry/remappings.txt | 4 ++ tests/ERC721/foundry/script/Counter.s.sol | 12 ------ tests/ERC721/foundry/src/Counter.sol | 14 ------- tests/ERC721/foundry/src/ExampleToken.sol | 41 +++++++++++++++++++ tests/ERC721/foundry/test/Counter.t.sol | 24 ----------- tests/ERC721/foundry/test/CryticTest.sol | 15 +++++++ tests/ERC721/foundry/test/CryticTestExt.sol | 40 ++++++++++++++++++ 15 files changed, 122 insertions(+), 100 deletions(-) create mode 100644 remappings.txt delete mode 100644 tests/ERC721/foundry/.github/workflows/test.yml delete mode 100644 tests/ERC721/foundry/.gitignore create mode 100644 tests/ERC721/foundry/.gitmodules create mode 100644 tests/ERC721/foundry/echidna-config-ext.yaml create mode 100644 tests/ERC721/foundry/echidna-config.yaml create mode 100644 tests/ERC721/foundry/remappings.txt delete mode 100644 tests/ERC721/foundry/script/Counter.s.sol delete mode 100644 tests/ERC721/foundry/src/Counter.sol create mode 100644 tests/ERC721/foundry/src/ExampleToken.sol delete mode 100644 tests/ERC721/foundry/test/Counter.t.sol create mode 100644 tests/ERC721/foundry/test/CryticTest.sol create mode 100644 tests/ERC721/foundry/test/CryticTestExt.sol diff --git a/.gitmodules b/.gitmodules index e600796..ca41865 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std - branch = v1.1.1 + branch = v1.5.2 [submodule "lib/solmate"] path = lib/solmate url = https://github.com/transmissions11/solmate @@ -18,3 +18,6 @@ path = lib/openzeppelin-contracts url = https://github.com/openzeppelin/openzeppelin-contracts branch = v4.8.0 +[submodule "tests/ERC721/foundry/lib/forge-std"] + path = tests/ERC721/foundry/lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 0000000..2374942 --- /dev/null +++ b/remappings.txt @@ -0,0 +1,6 @@ +ERC4626/=lib/ERC4626/contracts/ +ds-test/=lib/forge-std/lib/ds-test/src/ +erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ +forge-std/=lib/forge-std/src/ +openzeppelin-contracts/=lib/openzeppelin-contracts/ +solmate/=lib/solmate/src/ diff --git a/tests/ERC721/foundry/.github/workflows/test.yml b/tests/ERC721/foundry/.github/workflows/test.yml deleted file mode 100644 index 09880b1..0000000 --- a/tests/ERC721/foundry/.github/workflows/test.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: test - -on: workflow_dispatch - -env: - FOUNDRY_PROFILE: ci - -jobs: - check: - strategy: - fail-fast: true - - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Run Forge build - run: | - forge --version - forge build --sizes - id: build - - - name: Run Forge tests - run: | - forge test -vvv - id: test diff --git a/tests/ERC721/foundry/.gitignore b/tests/ERC721/foundry/.gitignore deleted file mode 100644 index 85198aa..0000000 --- a/tests/ERC721/foundry/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Compiler files -cache/ -out/ - -# Ignores development broadcast logs -!/broadcast -/broadcast/*/31337/ -/broadcast/**/dry-run/ - -# Docs -docs/ - -# Dotenv file -.env diff --git a/tests/ERC721/foundry/.gitmodules b/tests/ERC721/foundry/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/tests/ERC721/foundry/echidna-config-ext.yaml b/tests/ERC721/foundry/echidna-config-ext.yaml new file mode 100644 index 0000000..2a61138 --- /dev/null +++ b/tests/ERC721/foundry/echidna-config-ext.yaml @@ -0,0 +1,6 @@ +corpusDir: "echidna-corpus-ext" +testMode: assertion +testLimit: 10000 +deployer: "0x10000" +sender: ["0x10000", "0x20000", "0x30000"] +multi-abi: true diff --git a/tests/ERC721/foundry/echidna-config.yaml b/tests/ERC721/foundry/echidna-config.yaml new file mode 100644 index 0000000..ff562a5 --- /dev/null +++ b/tests/ERC721/foundry/echidna-config.yaml @@ -0,0 +1,5 @@ +corpusDir: "echidna-corpus" +testMode: assertion +testLimit: 10000 +deployer: "0x10000" +sender: ["0x10000", "0x20000", "0x30000"] diff --git a/tests/ERC721/foundry/foundry.toml b/tests/ERC721/foundry/foundry.toml index e6810b2..b84e65a 100644 --- a/tests/ERC721/foundry/foundry.toml +++ b/tests/ERC721/foundry/foundry.toml @@ -1,6 +1,6 @@ [profile.default] src = 'src' out = 'out' -libs = ['lib'] +libs = ['../../../lib','../../..'] # See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/tests/ERC721/foundry/remappings.txt b/tests/ERC721/foundry/remappings.txt new file mode 100644 index 0000000..473e7d7 --- /dev/null +++ b/tests/ERC721/foundry/remappings.txt @@ -0,0 +1,4 @@ +ds-test/=lib/forge-std/lib/ds-test/src/ +forge-std/=lib/forge-std/src/ +properties/=../../../contracts/ +@openzeppelin/=../../../lib/openzeppelin-contracts/ \ No newline at end of file diff --git a/tests/ERC721/foundry/script/Counter.s.sol b/tests/ERC721/foundry/script/Counter.s.sol deleted file mode 100644 index 0e546ab..0000000 --- a/tests/ERC721/foundry/script/Counter.s.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Script.sol"; - -contract CounterScript is Script { - function setUp() public {} - - function run() public { - vm.broadcast(); - } -} diff --git a/tests/ERC721/foundry/src/Counter.sol b/tests/ERC721/foundry/src/Counter.sol deleted file mode 100644 index aded799..0000000 --- a/tests/ERC721/foundry/src/Counter.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -contract Counter { - uint256 public number; - - function setNumber(uint256 newNumber) public { - number = newNumber; - } - - function increment() public { - number++; - } -} diff --git a/tests/ERC721/foundry/src/ExampleToken.sol b/tests/ERC721/foundry/src/ExampleToken.sol new file mode 100644 index 0000000..01a12c7 --- /dev/null +++ b/tests/ERC721/foundry/src/ExampleToken.sol @@ -0,0 +1,41 @@ +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "@openzeppelin/contracts/security/Pausable.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable, Pausable, Ownable { + constructor() ERC721("Example token", "EXT") {} + + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + + function mint(address to, uint256 tokenId) public virtual onlyOwner { + _mint(to, tokenId); + } + + // Overrides + + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + override(ERC721, ERC721Enumerable) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC721, ERC721Enumerable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} diff --git a/tests/ERC721/foundry/test/Counter.t.sol b/tests/ERC721/foundry/test/Counter.t.sol deleted file mode 100644 index 30235e8..0000000 --- a/tests/ERC721/foundry/test/Counter.t.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Test.sol"; -import "../src/Counter.sol"; - -contract CounterTest is Test { - Counter public counter; - - function setUp() public { - counter = new Counter(); - counter.setNumber(0); - } - - function testIncrement() public { - counter.increment(); - assertEq(counter.number(), 1); - } - - function testSetNumber(uint256 x) public { - counter.setNumber(x); - assertEq(counter.number(), x); - } -} diff --git a/tests/ERC721/foundry/test/CryticTest.sol b/tests/ERC721/foundry/test/CryticTest.sol new file mode 100644 index 0000000..b2f99be --- /dev/null +++ b/tests/ERC721/foundry/test/CryticTest.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.8.0; +import "properties/ERC721/internal/properties/ERC721BasicProperties.sol"; +import "../src/ExampleToken.sol"; + +contract CryticERC721InternalHarness is ExampleToken, CryticERC721BasicProperties { + constructor() { + // Setup balances for USER1, USER2 and USER3: + _mint(USER1, INITIAL_BALANCE); + _mint(USER2, INITIAL_BALANCE); + _mint(USER3, INITIAL_BALANCE); + // Setup total supply: + initialSupply = totalSupply(); + isMintableOrBurnable = true; + } +} diff --git a/tests/ERC721/foundry/test/CryticTestExt.sol b/tests/ERC721/foundry/test/CryticTestExt.sol new file mode 100644 index 0000000..ed9b2a8 --- /dev/null +++ b/tests/ERC721/foundry/test/CryticTestExt.sol @@ -0,0 +1,40 @@ +pragma solidity ^0.8.0; +import "../src/ExampleToken.sol"; +import {IERC721Mock} from "properties/ERC721/external/util/IERC721Mock.sol"; +import {CryticERC721ExternalBasicProperties} from "properties/ERC721/external/properties/ERC721xternalBasicProperties.sol"; + +contract CryticERC721ExternalHarness is CryticERC721ExternalBasicProperties { + + constructor() { + // Deploy ERC721 + token = IERC721Mock(address(new ERC721Mock())); + } + +} + +contract ERC721Mock is ExampleToken { + + // Address originating transactions in Echidna (must be equal to the `sender` configuration parameter) + address constant USER1 = address(0x10000); + address constant USER2 = address(0x20000); + address constant USER3 = address(0x30000); + + // Initial balance for users' accounts + uint256 constant INITIAL_BALANCE = 5; + + bool public isMintableOrBurnable; + uint256 public initialSupply; + constructor () { + for(uint256 i; i < INITIAL_BALANCE; i=i + 4) { + _mint(USER1, i); + _mint(USER2, i+1); + _mint(USER3, i+2); + _mint(msg.sender, i+3); + } + + + initialSupply = totalSupply(); + isMintableOrBurnable = true; + } + +} From 93fa7016cdc1257f2c617b35e10ebf7b75728c1a Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Thu, 30 Mar 2023 15:02:23 +0200 Subject: [PATCH 04/23] fixed imports, added some tests --- contracts/ERC4626/test/Solmate4626.sol | 2 +- contracts/ERC721/README.md | 75 ++++++++++++++++++ .../external/ERC721ExternalPropertyTests.sol | 10 +++ .../ERC721ExternalBasicProperties.sol | 8 +- .../ERC721/external/test/ERC721Compliant.sol | 33 ++++++++ .../external/test/ERC721NonCompliant.sol | 54 +++++++++++++ .../ERC721/external/test/echidna.config.yaml | 8 ++ .../test/standard/ERC721CompliantTests.sol | 15 ++++ .../test/standard/ERC721NonCompliantTests.sol | 15 ++++ .../test/standard/ERC721ShouldRevert.sol | 79 +++++++++++++++++++ .../external/util/ERC721ExternalTestBase.sol | 3 + .../ERC721/external/util/MockReceiver.sol | 20 +++++ .../internal/ERC721InternalPropertyTests.sol | 32 ++++++++ .../properties/ERC721BasicProperties.sol | 10 +-- .../properties/ERC721BurnableProperties.sol | 14 ++-- .../properties/ERC721MintableProperties.sol | 6 +- .../ERC721/internal/test/echidna.config.yaml | 7 ++ .../test/standard/ERC721Compliant.sol | 44 +++++++++++ .../test/standard/ERC721NonCompliant.sol | 55 +++++++++++++ .../ERC721/internal/util/ERC721TestBase.sol | 6 +- contracts/ERC721/util/IERC721Internal.sol | 11 +++ contracts/ERC721/util/OZERC721.sol | 28 +++++++ remappings.txt | 4 +- 23 files changed, 509 insertions(+), 30 deletions(-) create mode 100644 contracts/ERC721/README.md create mode 100644 contracts/ERC721/external/ERC721ExternalPropertyTests.sol create mode 100644 contracts/ERC721/external/test/ERC721Compliant.sol create mode 100644 contracts/ERC721/external/test/ERC721NonCompliant.sol create mode 100644 contracts/ERC721/external/test/echidna.config.yaml create mode 100644 contracts/ERC721/external/test/standard/ERC721CompliantTests.sol create mode 100644 contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol create mode 100644 contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol create mode 100644 contracts/ERC721/external/util/MockReceiver.sol create mode 100644 contracts/ERC721/internal/ERC721InternalPropertyTests.sol create mode 100644 contracts/ERC721/internal/test/echidna.config.yaml create mode 100644 contracts/ERC721/internal/test/standard/ERC721Compliant.sol create mode 100644 contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol create mode 100644 contracts/ERC721/util/IERC721Internal.sol create mode 100644 contracts/ERC721/util/OZERC721.sol diff --git a/contracts/ERC4626/test/Solmate4626.sol b/contracts/ERC4626/test/Solmate4626.sol index ffb94e6..a8d8143 100644 --- a/contracts/ERC4626/test/Solmate4626.sol +++ b/contracts/ERC4626/test/Solmate4626.sol @@ -29,6 +29,6 @@ contract TestHarness is CryticERC4626PropertyTests{ constructor () { TestERC20Token _asset = new TestERC20Token("Test Token", "TT", 18); ERC4626 _vault = new Solmate4626(ERC20(address(_asset))); - initialize(address(_vault), address(_asset)); + initialize(address(_vault), address(_asset), false); } } diff --git a/contracts/ERC721/README.md b/contracts/ERC721/README.md new file mode 100644 index 0000000..9bab335 --- /dev/null +++ b/contracts/ERC721/README.md @@ -0,0 +1,75 @@ + +# ERC721 Echidna Property Tests + +- [ERC721 Echidna Property Tests](#erc721-echidna-property-tests) + - [Consuming](#consuming) + - [Initial setup](#initial-setup) + - [Adding internal test methods to an ERC721](#adding-internal-test-methods-to-an-erc721) + - [Developing](#developing) + - [Properties Tested](#properties-tested) + - [Should revert](#should-revert) + +## Consuming + +### Initial setup +To use these properties to test a given vault implementation, see the readme in the project root. + +### Adding internal test methods to an ERC721 +Some properties of the ERC721 spec cannot be tested externally because testing them requires interactions between the test suite & functionality that is not defined in the spec. + +To compensate for this limitation, a vault under test may optionally implement a set of methods that allow such properties to be tested. See [IERC721Internal](util/IERC721Internal.sol) for the list of methods. + +These methods should be added to the ERC721 contract by a derived, test-environment-only contract to minimize changes to the production contract. When an ERC721 under test implements IERC721Internal, pass `true` to the test harness's `initialize()` function to enable the properties that require the internal interface: + +``` +contract MyERC721 is IERC721Internal { ... } + +contract MyERC721Testable is MyERC721, IERC721Internal { ... } + +contract TestHarness is CryticERC721InternalPropertyTests{ + constructor(...) { + [...] + initialize(true); + } +} +``` + +## Developing + +Before doing any development, run `forge install` to get dependencies sorted out. `forge build` will not work without the [Echidna remappings](internal/test/echidna.config.yaml). + +Running tests(used to validate the properties are working correctly): + +- Internal: +`echidna-test ./contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol --contract ERC721NonCompliant --config ./contracts/ERC721/internal/test/echidna.config.yaml` +- External: +`echidna-test ./contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` +Should cause these properties to fail: +- test_ERC721_external_ownerOfInvalidTokenMustRevert +- test_ERC721_external_balanceOfZeroAddressMustRevert +- test_ERC721_external_approvingInvalidTokenMustRevert +- test_ERC721_external_transferFromNotApproved +- test_ERC721_external_transferFromZeroAddress +- test_ERC721_external_transferToZeroAddress +- test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver + + + + + + +Run property tests against vanilla OpenZeppelin ERC721: + +- Internal: +`echidna-test ./contracts/ERC721/internal/test/standard/ERC721Compliant.sol --contract ERC721Compliant --config ./contracts/ERC721/internal/test/echidna.config.yaml` + +- External: +`echidna-test ./contracts/ERC721/external/test/standard/ERC721CompliantTests.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` + +[EIP-721 Spec](https://eips.ethereum.org/EIPS/eip-721) + +## Properties Tested + +### Should revert +- `ownerOf()` must revert for the zero address +- `safeTransferFrom()` must revert if the receiver does not implement onERC721Received \ No newline at end of file diff --git a/contracts/ERC721/external/ERC721ExternalPropertyTests.sol b/contracts/ERC721/external/ERC721ExternalPropertyTests.sol new file mode 100644 index 0000000..2096e6b --- /dev/null +++ b/contracts/ERC721/external/ERC721ExternalPropertyTests.sol @@ -0,0 +1,10 @@ +pragma solidity ^0.8.13; + +import {CryticERC721ExternalTestBase} from "./util/ERC721ExternalTestBase.sol"; +import {CryticERC721ExternalBasicProperties} from "./properties/ERC721ExternalBasicProperties.sol"; +import {CryticERC721ExternalBurnableProperties} from "./properties/ERC721ExternalBurnableProperties.sol"; +import {CryticERC721ExternalMintableProperties} from "./properties/ERC721ExternalMintableProperties.sol"; + +/// @notice Aggregator contract for various ERC721 property tests. Inherit from this & echidna will test all properties at the same time. +abstract contract CryticERC721ExternalPropertyTests is CryticERC721ExternalBasicProperties, CryticERC721ExternalMintableProperties, CryticERC721ExternalBurnableProperties { +} diff --git a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol index 8311a6e..9a169ef 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol @@ -75,6 +75,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes assertWithMsg(token.ownerOf(tokenId) == target, "Token owner not updated"); } + // transfer from zero address should revert function test_ERC721_external_transferFromZeroAddress(address target, uint256 tokenId) public virtual { require(target != address(this)); require(target != msg.sender); @@ -122,18 +123,15 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes } // safeTransferFrom reverts if receiver does not implement the callback - function test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver(address target) public virtual { + function test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver() public virtual { uint256 selfBalance = token.balanceOf(msg.sender); require(selfBalance > 0); - require(target != address(this)); - require(target != msg.sender); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); bool isApproved = token.isApprovedForAll(msg.sender, address(this)); address approved = token.getApproved(tokenId); require(approved == address(this) || isApproved); - require(!target.isContract()); - token.safeTransferFrom(msg.sender, target, tokenId); + token.safeTransferFrom(msg.sender, address(mockUnsafeReceiver), tokenId); assertWithMsg(false, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); } diff --git a/contracts/ERC721/external/test/ERC721Compliant.sol b/contracts/ERC721/external/test/ERC721Compliant.sol new file mode 100644 index 0000000..f20eb5c --- /dev/null +++ b/contracts/ERC721/external/test/ERC721Compliant.sol @@ -0,0 +1,33 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; + +contract ERC721Compliant is ERC721, ERC721Enumerable { + + uint256 public counter; + uint256 public maxSupply; + + constructor() ERC721("OZERC721","OZ") { + maxSupply = 100; + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ERC721, ERC721Enumerable) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC721, ERC721Enumerable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} \ No newline at end of file diff --git a/contracts/ERC721/external/test/ERC721NonCompliant.sol b/contracts/ERC721/external/test/ERC721NonCompliant.sol new file mode 100644 index 0000000..e5e1589 --- /dev/null +++ b/contracts/ERC721/external/test/ERC721NonCompliant.sol @@ -0,0 +1,54 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; + +contract ERC721NonCompliant is ERC721, ERC721Enumerable { + + uint256 public counter; + uint256 public maxSupply; + + constructor() ERC721("OZERC721","OZ") { + maxSupply = 100; + } + + function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { + //require(owner != address(0), "ERC721: address zero is not a valid owner"); + return owner == address(0) ? 0 : super.balanceOf(owner); + } + + function ownerOf(uint256 tokenId) public view virtual override(ERC721, IERC721) returns (address) { + address owner = _ownerOf(tokenId); + //require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ERC721, ERC721Enumerable) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC721, ERC721Enumerable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + function _customMint(uint256 amount) public virtual { + for (uint256 i; i < amount; i++) { + _mint(msg.sender, counter++); + } + } + + function _customMaxSupply() public virtual view returns (uint256) { + return maxSupply; + } +} \ No newline at end of file diff --git a/contracts/ERC721/external/test/echidna.config.yaml b/contracts/ERC721/external/test/echidna.config.yaml new file mode 100644 index 0000000..6b3e570 --- /dev/null +++ b/contracts/ERC721/external/test/echidna.config.yaml @@ -0,0 +1,8 @@ +coverage: true +multi-abi: true +corpusDir: "corpus" +testMode: assertion +testLimit: 100000 +cryticArgs: + - --solc-remaps + - ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ solmate/=lib/solmate/ @openzeppelin/=lib/openzeppelin-contracts/ \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol b/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol new file mode 100644 index 0000000..9be7b70 --- /dev/null +++ b/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.8.0; + +import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; +import {ERC721Compliant} from "../ERC721Compliant.sol"; +import {IERC721Mock} from "../../util/IERC721Mock.sol"; + +contract TestHarness is CryticERC721ExternalPropertyTests { + + constructor() { + token = IERC721Mock(address(new ERC721Compliant())); + } + + function _customMint(uint256 amount) internal virtual override {} + +} \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol b/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol new file mode 100644 index 0000000..a1799e0 --- /dev/null +++ b/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.8.0; + +import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; +import {ERC721NonCompliant} from "../ERC721NonCompliant.sol"; +import {IERC721Mock} from "../../util/IERC721Mock.sol"; + +contract TestHarness is CryticERC721ExternalPropertyTests { + + constructor() { + token = IERC721Mock(address(new ERC721NonCompliant())); + } + + function _customMint(uint256 amount) internal virtual override {} + +} \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol b/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol new file mode 100644 index 0000000..d750c1c --- /dev/null +++ b/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol @@ -0,0 +1,79 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; +import {IERC721Mock} from "../../util/IERC721Mock.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; + +contract ERC721ShouldRevert is ERC721, ERC721Enumerable { + + uint256 public counter; + uint256 public maxSupply; + bool public isMintableOrBurnable; + + constructor() ERC721("OZERC721","OZ") { + maxSupply = 100; + isMintableOrBurnable = true; + } + + function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { + //require(owner != address(0), "ERC721: address zero is not a valid owner"); + return owner == address(0) ? 0 : super.balanceOf(owner); + } + + function ownerOf(uint256 tokenId) public view virtual override(ERC721, IERC721) returns (address) { + address owner = _ownerOf(tokenId); + //require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + function approve(address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + // removed validation + + _approve(to, tokenId); + + + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ERC721, ERC721Enumerable) + { + ERC721Enumerable._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC721, ERC721Enumerable) + returns (bool) + { + return ERC721Enumerable.supportsInterface(interfaceId); + } + + function _customMint(uint256 amount) public virtual { + for (uint256 i; i < amount; i++) { + _mint(msg.sender, counter++); + } + } + + function _customMaxSupply() public virtual view returns (uint256) { + return maxSupply; + } +} + +contract TestHarness is CryticERC721ExternalPropertyTests { + + constructor() { + token = IERC721Mock(address(new ERC721ShouldRevert())); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); + } + + function _customMint(uint256 amount) internal virtual override {} + +} \ No newline at end of file diff --git a/contracts/ERC721/external/util/ERC721ExternalTestBase.sol b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol index cfe4eb5..f50c3ea 100644 --- a/contracts/ERC721/external/util/ERC721ExternalTestBase.sol +++ b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol @@ -4,11 +4,14 @@ import "../../../util/PropertiesHelper.sol"; import "./IERC721Mock.sol"; import "../../../util/PropertiesConstants.sol"; import "@openzeppelin/contracts/utils/Address.sol"; +import {MockReceiver} from "./MockReceiver.sol"; abstract contract CryticERC721ExternalTestBase is PropertiesAsserts, PropertiesConstants { IERC721Mock token; + MockReceiver mockSafeReceiver; + MockReceiver mockUnsafeReceiver; constructor() { } diff --git a/contracts/ERC721/external/util/MockReceiver.sol b/contracts/ERC721/external/util/MockReceiver.sol new file mode 100644 index 0000000..618ac84 --- /dev/null +++ b/contracts/ERC721/external/util/MockReceiver.sol @@ -0,0 +1,20 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + + +contract MockReceiver is ERC721Holder { + bool shouldReceive; + + constructor(bool _shouldReceive) { + shouldReceive = _shouldReceive; + } + + function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { + if (shouldReceive) { + return this.onERC721Received.selector; + } + + return bytes4(0); + } +} \ No newline at end of file diff --git a/contracts/ERC721/internal/ERC721InternalPropertyTests.sol b/contracts/ERC721/internal/ERC721InternalPropertyTests.sol new file mode 100644 index 0000000..f278bf8 --- /dev/null +++ b/contracts/ERC721/internal/ERC721InternalPropertyTests.sol @@ -0,0 +1,32 @@ +pragma solidity ^0.8.13; + +import {CryticERC721TestBase} from "./util/ERC721TestBase.sol"; +import {CryticERC721BasicProperties} from "./properties/ERC721BasicProperties.sol"; +import {CryticERC721BurnableProperties} from "./properties/ERC721BurnableProperties.sol"; +import {CryticERC721MintableProperties} from "./properties/ERC721MintableProperties.sol"; + +/// @notice Aggregator contract for various ERC721 property tests. Inherit from this & echidna will test all properties at the same time. +abstract contract CryticERC721InternalPropertyTests is CryticERC721BasicProperties, CryticERC721MintableProperties, CryticERC721BurnableProperties { + constructor() { + isMintableOrBurnable = true; + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(CryticERC721BurnableProperties, CryticERC721TestBase) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(CryticERC721BurnableProperties, CryticERC721TestBase) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol index 83f3c8a..261c622 100644 --- a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -2,12 +2,9 @@ pragma solidity ^0.8.13; import "../util/ERC721TestBase.sol"; -abstract contract CryticERC721BasicProperties is CryticERC721Base { +abstract contract CryticERC721BasicProperties is CryticERC721TestBase { using Address for address; - constructor() { - } - //////////////////////////////////////// // Properties @@ -134,9 +131,10 @@ abstract contract CryticERC721BasicProperties is CryticERC721Base { address approved = getApproved(tokenId); require(approved == address(this) || isApproved); require(!target.isContract()); - + require(ownerOf(tokenId) == msg.sender); + safeTransferFrom(msg.sender, target, tokenId); - assertWithMsg(false, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); + assertWithMsg(ownerOf(tokenId) == msg.sender, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); } // todo test_ERC721_setApprovalForAllWorksAsExpected diff --git a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol index 8752db0..d2d09d7 100644 --- a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol @@ -1,16 +1,12 @@ pragma solidity ^0.8.13; -import "../util/ERC721ExternalTestBase.sol"; +import "../util/ERC721TestBase.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; -abstract contract CryticERC721BurnableProperties is CryticERC721ExternalTestBase, ERC721Burnable { +abstract contract CryticERC721BurnableProperties is CryticERC721TestBase, ERC721Burnable { using Address for address; - constructor() { - isMintableOrBurnable = true; - } - //////////////////////////////////////// // Properties @@ -81,7 +77,8 @@ abstract contract CryticERC721BurnableProperties is CryticERC721ExternalTestBase function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal - override(ERC721, CryticERC721Base) + virtual + override(ERC721, CryticERC721TestBase) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } @@ -89,7 +86,8 @@ abstract contract CryticERC721BurnableProperties is CryticERC721ExternalTestBase function supportsInterface(bytes4 interfaceId) public view - override(ERC721, CryticERC721Base) + virtual + override(ERC721, CryticERC721TestBase) returns (bool) { return super.supportsInterface(interfaceId); diff --git a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol index 015e692..7757092 100644 --- a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol @@ -2,13 +2,9 @@ pragma solidity ^0.8.13; import "../util/ERC721TestBase.sol"; -abstract contract CryticERC721MintableProperties is CryticERC721Base { +abstract contract CryticERC721MintableProperties is CryticERC721TestBase { using Address for address; - constructor() { - isMintableOrBurnable = true; - } - //////////////////////////////////////// // Properties // mint increases the total supply diff --git a/contracts/ERC721/internal/test/echidna.config.yaml b/contracts/ERC721/internal/test/echidna.config.yaml new file mode 100644 index 0000000..9b89855 --- /dev/null +++ b/contracts/ERC721/internal/test/echidna.config.yaml @@ -0,0 +1,7 @@ +coverage: true +corpusDir: "corpus" +testMode: assertion +testLimit: 100000 +cryticArgs: + - --solc-remaps + - ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ solmate/=lib/solmate/ @openzeppelin/=lib/openzeppelin-contracts/ \ No newline at end of file diff --git a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol new file mode 100644 index 0000000..0407c0c --- /dev/null +++ b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol @@ -0,0 +1,44 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "../../ERC721InternalPropertyTests.sol"; + +contract ERC721Compliant is ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests { + + uint256 public counter; + uint256 public maxSupply; + + constructor() ERC721("OZERC721","OZ") { + maxSupply = 100; + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + function _customMint(uint256 amount) internal virtual override { + for (uint256 i; i < amount; i++) { + _safeMint(msg.sender, counter++); + } + } + + function _customMaxSupply() internal virtual override view returns (uint256) { + return maxSupply; + } +} \ No newline at end of file diff --git a/contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol b/contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol new file mode 100644 index 0000000..3f255cf --- /dev/null +++ b/contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol @@ -0,0 +1,55 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "../../ERC721InternalPropertyTests.sol"; + +contract ERC721NonCompliant is ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests { + + uint256 public counter; + uint256 public maxSupply; + + constructor() ERC721("OZERC721","OZ") { + maxSupply = 100; + } + + function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { + //require(owner != address(0), "ERC721: address zero is not a valid owner"); + return owner == address(0) ? 0 : super.balanceOf(owner); + } + + function ownerOf(uint256 tokenId) public view virtual override(ERC721, IERC721) returns (address) { + address owner = _ownerOf(tokenId); + //require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + function _customMint(uint256 amount) internal virtual override { + for (uint256 i; i < amount; i++) { + _mint(msg.sender, counter++); + } + } + + function _customMaxSupply() internal virtual override view returns (uint256) { + return maxSupply; + } +} \ No newline at end of file diff --git a/contracts/ERC721/internal/util/ERC721TestBase.sol b/contracts/ERC721/internal/util/ERC721TestBase.sol index 4b38d80..869c4c9 100644 --- a/contracts/ERC721/internal/util/ERC721TestBase.sol +++ b/contracts/ERC721/internal/util/ERC721TestBase.sol @@ -5,19 +5,18 @@ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "../../../util/PropertiesConstants.sol"; import "../../../util/PropertiesHelper.sol"; -abstract contract CryticERC721Base is ERC721, ERC721Enumerable, PropertiesAsserts, PropertiesConstants { +abstract contract CryticERC721TestBase is ERC721, ERC721Enumerable, PropertiesAsserts, PropertiesConstants { // Is the contract allowed to change its total supply? bool isMintableOrBurnable; bool hasMaxSupply; - constructor() { - } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal + virtual override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); @@ -26,6 +25,7 @@ abstract contract CryticERC721Base is ERC721, ERC721Enumerable, PropertiesAssert function supportsInterface(bytes4 interfaceId) public view + virtual override(ERC721, ERC721Enumerable) returns (bool) { diff --git a/contracts/ERC721/util/IERC721Internal.sol b/contracts/ERC721/util/IERC721Internal.sol new file mode 100644 index 0000000..d0ca88c --- /dev/null +++ b/contracts/ERC721/util/IERC721Internal.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; + +interface IERC721Internal is IERC721, IERC721Enumerable { + function isMintableOrBurnable() external returns (bool); + function burn(uint256 tokenId) external; + function _customMint(uint256 amount) external; + function _customMaxSupply() external view returns (uint256); +} \ No newline at end of file diff --git a/contracts/ERC721/util/OZERC721.sol b/contracts/ERC721/util/OZERC721.sol new file mode 100644 index 0000000..b84c750 --- /dev/null +++ b/contracts/ERC721/util/OZERC721.sol @@ -0,0 +1,28 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; + +contract OZERC721 is ERC721, ERC721Enumerable { + + constructor() ERC721("OZERC721","OZ") {} + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ERC721, ERC721Enumerable) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC721, ERC721Enumerable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} \ No newline at end of file diff --git a/remappings.txt b/remappings.txt index 2374942..c40d8fe 100644 --- a/remappings.txt +++ b/remappings.txt @@ -2,5 +2,5 @@ ERC4626/=lib/ERC4626/contracts/ ds-test/=lib/forge-std/lib/ds-test/src/ erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ forge-std/=lib/forge-std/src/ -openzeppelin-contracts/=lib/openzeppelin-contracts/ -solmate/=lib/solmate/src/ +@openzeppelin/=lib/openzeppelin-contracts/ +solmate/=lib/solmate/ From fb3f417210a8459302383d43227c919a76986ff2 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Thu, 30 Mar 2023 16:23:37 +0200 Subject: [PATCH 05/23] fixed external mint tests, added should-revert tests --- .../ERC721ExternalBasicProperties.sol | 1 + .../ERC721ExternalMintableProperties.sol | 24 ++++----- .../ERC721/external/test/ERC721Compliant.sol | 15 ++++++ .../external/test/ERC721NonCompliant.sol | 25 ++++++---- .../test/standard/ERC721CompliantTests.sol | 9 ++-- .../test/standard/ERC721NonCompliantTests.sol | 9 ++-- .../test/standard/ERC721ShouldRevert.sol | 50 +++++++++++++++---- .../external/util/ERC721ExternalTestBase.sol | 4 +- contracts/ERC721/util/IERC721Internal.sol | 2 +- 9 files changed, 97 insertions(+), 42 deletions(-) diff --git a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol index 9a169ef..a948399 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol @@ -26,6 +26,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes // Approving an invalid token should throw function test_ERC721_external_approvingInvalidTokenMustRevert() public virtual { token.approve(address(0), type(uint256).max); + assertWithMsg(false, "Breakpoint"); assertWithMsg(false, "Approving an invalid token should have reverted"); } diff --git a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol index f931190..67687e0 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol @@ -13,28 +13,28 @@ abstract contract CryticERC721ExternalMintableProperties is CryticERC721External // mint increases the total supply function test_ERC721_external_mintIncreasesSupply(uint256 amount) public virtual { require(token.isMintableOrBurnable()); - uint256 selfBalance = token.balanceOf(msg.sender); + require(amount > 0); + uint256 selfBalance = token.balanceOf(address(this)); uint256 oldTotalSupply = token.totalSupply(); - _customMint(amount); - + token._customMint(address(this), amount); + assertEq(oldTotalSupply + amount, token.totalSupply(), "Total supply was not correctly increased"); - assertEq(selfBalance + amount, token.balanceOf(msg.sender), "Receiver supply was not correctly increased"); + assertEq(selfBalance + amount, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); } // mint creates a fresh token function test_ERC721_external_mintCreatesFreshToken(uint256 amount) public virtual { require(token.isMintableOrBurnable()); - uint256 selfBalance = token.balanceOf(msg.sender); + require(amount > 0); + uint256 selfBalance = token.balanceOf(address(this)); uint256 endIndex = selfBalance + amount; - _customMint(amount); + token._customMint(address(this), amount); for(uint256 i = selfBalance; i < endIndex; i++) { - uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, i); - assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Token ID was not minted to receiver"); + uint256 tokenId = token.tokenOfOwnerByIndex(address(this), i); + assertWithMsg(token.ownerOf(tokenId) == address(this), "Token ID was not minted to receiver"); } - assertEq(selfBalance + amount, token.balanceOf(msg.sender), "Receiver supply was not correctly increased"); - } - // Wrappers - function _customMint(uint256 amount) internal virtual; + assertEq(selfBalance + amount, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); + } } diff --git a/contracts/ERC721/external/test/ERC721Compliant.sol b/contracts/ERC721/external/test/ERC721Compliant.sol index f20eb5c..02c6517 100644 --- a/contracts/ERC721/external/test/ERC721Compliant.sol +++ b/contracts/ERC721/external/test/ERC721Compliant.sol @@ -7,9 +7,24 @@ contract ERC721Compliant is ERC721, ERC721Enumerable { uint256 public counter; uint256 public maxSupply; + bool public isMintableOrBurnable; constructor() ERC721("OZERC721","OZ") { maxSupply = 100; + isMintableOrBurnable = true; + } + + + function _customMint(address to, uint256 amount) public virtual { + maxSupply += amount; + for (uint256 i; i < amount; i++) { + _mint(to, counter++); + } + + } + + function _customMaxSupply() public virtual view returns (uint256) { + return maxSupply; } // The following functions are overrides required by Solidity. diff --git a/contracts/ERC721/external/test/ERC721NonCompliant.sol b/contracts/ERC721/external/test/ERC721NonCompliant.sol index e5e1589..a1d5157 100644 --- a/contracts/ERC721/external/test/ERC721NonCompliant.sol +++ b/contracts/ERC721/external/test/ERC721NonCompliant.sol @@ -7,9 +7,12 @@ contract ERC721NonCompliant is ERC721, ERC721Enumerable { uint256 public counter; uint256 public maxSupply; + bool public isMintableOrBurnable; + constructor() ERC721("OZERC721","OZ") { maxSupply = 100; + isMintableOrBurnable = true; } function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { @@ -22,6 +25,18 @@ contract ERC721NonCompliant is ERC721, ERC721Enumerable { //require(owner != address(0), "ERC721: invalid token ID"); return owner; } + + function _customMint(address to, uint256 amount) public virtual { + maxSupply += amount; + + for (uint256 i; i < amount; i++) { + _mint(to, counter++); + } + } + + function _customMaxSupply() public virtual view returns (uint256) { + return maxSupply; + } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) @@ -41,14 +56,4 @@ contract ERC721NonCompliant is ERC721, ERC721Enumerable { { return super.supportsInterface(interfaceId); } - - function _customMint(uint256 amount) public virtual { - for (uint256 i; i < amount; i++) { - _mint(msg.sender, counter++); - } - } - - function _customMaxSupply() public virtual view returns (uint256) { - return maxSupply; - } } \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol b/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol index 9be7b70..3116d55 100644 --- a/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol +++ b/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol @@ -2,14 +2,15 @@ pragma solidity ^0.8.0; import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; import {ERC721Compliant} from "../ERC721Compliant.sol"; -import {IERC721Mock} from "../../util/IERC721Mock.sol"; +import {IERC721Internal} from "../../../util/IERC721Internal.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; contract TestHarness is CryticERC721ExternalPropertyTests { constructor() { - token = IERC721Mock(address(new ERC721Compliant())); + token = IERC721Internal(address(new ERC721Compliant())); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); } - function _customMint(uint256 amount) internal virtual override {} - } \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol b/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol index a1799e0..1e134d9 100644 --- a/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol +++ b/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol @@ -2,14 +2,15 @@ pragma solidity ^0.8.0; import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; import {ERC721NonCompliant} from "../ERC721NonCompliant.sol"; -import {IERC721Mock} from "../../util/IERC721Mock.sol"; +import {IERC721Internal} from "../../../util/IERC721Internal.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; contract TestHarness is CryticERC721ExternalPropertyTests { constructor() { - token = IERC721Mock(address(new ERC721NonCompliant())); + token = IERC721Internal(address(new ERC721NonCompliant())); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); } - function _customMint(uint256 amount) internal virtual override {} - } \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol b/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol index d750c1c..29210c6 100644 --- a/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol +++ b/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol @@ -3,10 +3,11 @@ pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; -import {IERC721Mock} from "../../util/IERC721Mock.sol"; +import {IERC721Internal} from "../../../util/IERC721Internal.sol"; import {MockReceiver} from "../../util/MockReceiver.sol"; contract ERC721ShouldRevert is ERC721, ERC721Enumerable { + using Address for address; uint256 public counter; uint256 public maxSupply; @@ -29,11 +30,42 @@ contract ERC721ShouldRevert is ERC721, ERC721Enumerable { } function approve(address to, uint256 tokenId) public virtual override(ERC721, IERC721) { - // removed validation + if(_exists(tokenId)) { + super.approve(to, tokenId); + } - _approve(to, tokenId); - + // Does not revert if token doesn't exist + } + function transferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + //solhint-disable-next-line max-line-length + //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + if (from == address(0)) { + _mint(to, tokenId); + } else if (getApproved(tokenId) != msg.sender && !isApprovedForAll(from, msg.sender) || to == address(0)) { + _burn(tokenId); + _mint(to, tokenId); + } else { + ERC721._transfer(from, to, tokenId); + } + } + + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + if (to.isContract()) { + try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, "") returns (bytes4 retval) { + if (retval != IERC721Receiver.onERC721Received.selector) { + _transfer(from, to, tokenId); + } else { + safeTransferFrom(from, to, tokenId, ""); + } + + } catch (bytes memory reason) { + _transfer(from, to, tokenId); + } + } else { + safeTransferFrom(from, to, tokenId, ""); + } + } // The following functions are overrides required by Solidity. @@ -55,9 +87,11 @@ contract ERC721ShouldRevert is ERC721, ERC721Enumerable { return ERC721Enumerable.supportsInterface(interfaceId); } - function _customMint(uint256 amount) public virtual { + function _customMint(address to, uint256 amount) public virtual { + maxSupply += amount; + for (uint256 i; i < amount; i++) { - _mint(msg.sender, counter++); + _mint(to, counter++); } } @@ -69,11 +103,9 @@ contract ERC721ShouldRevert is ERC721, ERC721Enumerable { contract TestHarness is CryticERC721ExternalPropertyTests { constructor() { - token = IERC721Mock(address(new ERC721ShouldRevert())); + token = IERC721Internal(address(new ERC721ShouldRevert())); mockSafeReceiver = new MockReceiver(true); mockUnsafeReceiver = new MockReceiver(false); } - function _customMint(uint256 amount) internal virtual override {} - } \ No newline at end of file diff --git a/contracts/ERC721/external/util/ERC721ExternalTestBase.sol b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol index f50c3ea..c13656c 100644 --- a/contracts/ERC721/external/util/ERC721ExternalTestBase.sol +++ b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol @@ -1,7 +1,7 @@ pragma solidity ^0.8.0; import "../../../util/PropertiesHelper.sol"; -import "./IERC721Mock.sol"; +import "../../util/IERC721Internal.sol"; import "../../../util/PropertiesConstants.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import {MockReceiver} from "./MockReceiver.sol"; @@ -9,7 +9,7 @@ import {MockReceiver} from "./MockReceiver.sol"; abstract contract CryticERC721ExternalTestBase is PropertiesAsserts, PropertiesConstants { - IERC721Mock token; + IERC721Internal token; MockReceiver mockSafeReceiver; MockReceiver mockUnsafeReceiver; diff --git a/contracts/ERC721/util/IERC721Internal.sol b/contracts/ERC721/util/IERC721Internal.sol index d0ca88c..aeddad6 100644 --- a/contracts/ERC721/util/IERC721Internal.sol +++ b/contracts/ERC721/util/IERC721Internal.sol @@ -6,6 +6,6 @@ import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; interface IERC721Internal is IERC721, IERC721Enumerable { function isMintableOrBurnable() external returns (bool); function burn(uint256 tokenId) external; - function _customMint(uint256 amount) external; + function _customMint(address to, uint256 amount) external; function _customMaxSupply() external view returns (uint256); } \ No newline at end of file From cb24d21eee73c1a5bf1705feb3c82c728d333bfd Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Thu, 30 Mar 2023 18:08:20 +0200 Subject: [PATCH 06/23] fixed ERC721 internal properties testing not starting up --- contracts/ERC721/README.md | 3 +- .../external/test/ERC721NonCompliant.sol | 59 ---------- .../test/standard/ERC721NonCompliantTests.sol | 16 --- .../internal/ERC721InternalPropertyTests.sol | 3 - .../properties/ERC721BasicProperties.sol | 14 ++- .../test/standard/ERC721Compliant.sol | 27 +++-- .../test/standard/ERC721ShouldRevert.sol | 109 ++++++++++++++++++ .../ERC721/internal/util/ERC721TestBase.sol | 7 +- .../ERC721/internal/util/MockReceiver.sol | 20 ++++ contracts/ERC721/util/OZERC721.sol | 28 ----- 10 files changed, 162 insertions(+), 124 deletions(-) delete mode 100644 contracts/ERC721/external/test/ERC721NonCompliant.sol delete mode 100644 contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol create mode 100644 contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol create mode 100644 contracts/ERC721/internal/util/MockReceiver.sol delete mode 100644 contracts/ERC721/util/OZERC721.sol diff --git a/contracts/ERC721/README.md b/contracts/ERC721/README.md index 9bab335..9b9a48d 100644 --- a/contracts/ERC721/README.md +++ b/contracts/ERC721/README.md @@ -41,9 +41,10 @@ Before doing any development, run `forge install` to get dependencies sorted out Running tests(used to validate the properties are working correctly): - Internal: -`echidna-test ./contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol --contract ERC721NonCompliant --config ./contracts/ERC721/internal/test/echidna.config.yaml` +`echidna-test ./contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol --contract TestHarness --config ./contracts/ERC721/internal/test/echidna.config.yaml` - External: `echidna-test ./contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` + Should cause these properties to fail: - test_ERC721_external_ownerOfInvalidTokenMustRevert - test_ERC721_external_balanceOfZeroAddressMustRevert diff --git a/contracts/ERC721/external/test/ERC721NonCompliant.sol b/contracts/ERC721/external/test/ERC721NonCompliant.sol deleted file mode 100644 index a1d5157..0000000 --- a/contracts/ERC721/external/test/ERC721NonCompliant.sol +++ /dev/null @@ -1,59 +0,0 @@ -pragma solidity ^0.8.13; - -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; - -contract ERC721NonCompliant is ERC721, ERC721Enumerable { - - uint256 public counter; - uint256 public maxSupply; - bool public isMintableOrBurnable; - - - constructor() ERC721("OZERC721","OZ") { - maxSupply = 100; - isMintableOrBurnable = true; - } - - function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { - //require(owner != address(0), "ERC721: address zero is not a valid owner"); - return owner == address(0) ? 0 : super.balanceOf(owner); - } - - function ownerOf(uint256 tokenId) public view virtual override(ERC721, IERC721) returns (address) { - address owner = _ownerOf(tokenId); - //require(owner != address(0), "ERC721: invalid token ID"); - return owner; - } - - function _customMint(address to, uint256 amount) public virtual { - maxSupply += amount; - - for (uint256 i; i < amount; i++) { - _mint(to, counter++); - } - } - - function _customMaxSupply() public virtual view returns (uint256) { - return maxSupply; - } - - // The following functions are overrides required by Solidity. - function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) - internal - virtual - override(ERC721, ERC721Enumerable) - { - super._beforeTokenTransfer(from, to, tokenId, batchSize); - } - - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC721, ERC721Enumerable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol b/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol deleted file mode 100644 index 1e134d9..0000000 --- a/contracts/ERC721/external/test/standard/ERC721NonCompliantTests.sol +++ /dev/null @@ -1,16 +0,0 @@ -pragma solidity ^0.8.0; - -import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; -import {ERC721NonCompliant} from "../ERC721NonCompliant.sol"; -import {IERC721Internal} from "../../../util/IERC721Internal.sol"; -import {MockReceiver} from "../../util/MockReceiver.sol"; - -contract TestHarness is CryticERC721ExternalPropertyTests { - - constructor() { - token = IERC721Internal(address(new ERC721NonCompliant())); - mockSafeReceiver = new MockReceiver(true); - mockUnsafeReceiver = new MockReceiver(false); - } - -} \ No newline at end of file diff --git a/contracts/ERC721/internal/ERC721InternalPropertyTests.sol b/contracts/ERC721/internal/ERC721InternalPropertyTests.sol index f278bf8..ff5002b 100644 --- a/contracts/ERC721/internal/ERC721InternalPropertyTests.sol +++ b/contracts/ERC721/internal/ERC721InternalPropertyTests.sol @@ -7,9 +7,6 @@ import {CryticERC721MintableProperties} from "./properties/ERC721MintablePropert /// @notice Aggregator contract for various ERC721 property tests. Inherit from this & echidna will test all properties at the same time. abstract contract CryticERC721InternalPropertyTests is CryticERC721BasicProperties, CryticERC721MintableProperties, CryticERC721BurnableProperties { - constructor() { - isMintableOrBurnable = true; - } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol index 261c622..398360e 100644 --- a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -30,17 +30,20 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { // transferFrom a token that the caller is not approved for should revert function test_ERC721_transferFromNotApproved(address target) public virtual { - uint256 selfBalance = balanceOf(msg.sender); + uint256 selfBalance = balanceOf(target); require(selfBalance > 0); require(target != address(this)); require(target != msg.sender); - uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = isApprovedForAll(msg.sender, address(this)); + uint tokenId = tokenOfOwnerByIndex(target, 0); + bool isApproved = isApprovedForAll(target, address(this)); address approved = getApproved(tokenId); require(approved != address(this) && !isApproved); + require(ownerOf(tokenId) == target); - transferFrom(msg.sender, target, tokenId); + transferFrom(target, msg.sender, tokenId); + assertWithMsg(ownerOf(tokenId) == target, "Target"); assertWithMsg(ownerOf(tokenId) == msg.sender, "Transferred a token without being approved."); + } // transferFrom should reset approval for that token @@ -130,10 +133,9 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { bool isApproved = isApprovedForAll(msg.sender, address(this)); address approved = getApproved(tokenId); require(approved == address(this) || isApproved); - require(!target.isContract()); require(ownerOf(tokenId) == msg.sender); - safeTransferFrom(msg.sender, target, tokenId); + safeTransferFrom(msg.sender, address(unsafeReceiver), tokenId); assertWithMsg(ownerOf(tokenId) == msg.sender, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); } diff --git a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol index 0407c0c..349b208 100644 --- a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol +++ b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol @@ -2,22 +2,35 @@ pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import "../../ERC721InternalPropertyTests.sol"; +import {CryticERC721InternalPropertyTests} from "../../ERC721InternalPropertyTests.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; -contract ERC721Compliant is ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests { + +contract ERC721Compliant is CryticERC721InternalPropertyTests { uint256 public counter; uint256 public maxSupply; - constructor() ERC721("OZERC721","OZ") { + constructor() ERC721("ERC721Compliant","Compliant") { + isMintableOrBurnable = true; maxSupply = 100; + safeReceiver = new MockReceiver(true); + unsafeReceiver = new MockReceiver(false); + + } + + function mint(uint256 amount) public { + //require(totalSupply() + amount <= maxSupply); + for (uint256 i; i < amount; i++) { + _mint(msg.sender, counter++); + } } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal virtual - override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) + override(CryticERC721InternalPropertyTests) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } @@ -26,16 +39,14 @@ contract ERC721Compliant is ERC721, ERC721Enumerable, CryticERC721InternalProper public view virtual - override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) + override(CryticERC721InternalPropertyTests) returns (bool) { return super.supportsInterface(interfaceId); } function _customMint(uint256 amount) internal virtual override { - for (uint256 i; i < amount; i++) { - _safeMint(msg.sender, counter++); - } + mint(amount); } function _customMaxSupply() internal virtual override view returns (uint256) { diff --git a/contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol b/contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol new file mode 100644 index 0000000..81cd25c --- /dev/null +++ b/contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol @@ -0,0 +1,109 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import {CryticERC721InternalPropertyTests} from "../../ERC721InternalPropertyTests.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; + +contract ERC721ShouldRevertInternal is CryticERC721InternalPropertyTests { + using Address for address; + + uint256 public counter; + uint256 public maxSupply; + + constructor() ERC721("ERC721ShouldRevert","ERC721ShouldRevert") { + maxSupply = 100; + isMintableOrBurnable = true; + hasMaxSupply = false; + safeReceiver = new MockReceiver(true); + unsafeReceiver = new MockReceiver(false); + } + + function mint(uint256 amount) public { + //require(totalSupply() + amount <= maxSupply); + for (uint256 i; i < amount; i++) { + _mint(msg.sender, counter++); + } + } + + function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { + //require(owner != address(0), "ERC721: address zero is not a valid owner"); + return owner == address(0) ? 0 : super.balanceOf(owner); + } + + function ownerOf(uint256 tokenId) public view virtual override(ERC721, IERC721) returns (address) { + address owner = _ownerOf(tokenId); + //require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + function approve(address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + if(_exists(tokenId)) { + super.approve(to, tokenId); + } + + // Does not revert if token doesn't exist + } + + function transferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + //solhint-disable-next-line max-line-length + //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + if (from == address(0)) { + _mint(to, tokenId); + } else if (getApproved(tokenId) != msg.sender && !isApprovedForAll(from, msg.sender) || to == address(0)) { + _burn(tokenId); + _mint(to, tokenId); + } else { + ERC721._transfer(from, to, tokenId); + } + } + + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + if (to.isContract()) { + try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, "") returns (bytes4 retval) { + if (retval != IERC721Receiver.onERC721Received.selector) { + _transfer(from, to, tokenId); + } else { + safeTransferFrom(from, to, tokenId, ""); + } + + } catch (bytes memory reason) { + _transfer(from, to, tokenId); + } + } else { + safeTransferFrom(from, to, tokenId, ""); + } + + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(CryticERC721InternalPropertyTests) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(CryticERC721InternalPropertyTests) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + function _customMint(uint256 amount) internal virtual override { + mint(amount); + } + + function _customMaxSupply() internal virtual override view returns (uint256) { + return maxSupply; + } +} + +contract TestHarness is ERC721ShouldRevertInternal { + constructor() {} +} \ No newline at end of file diff --git a/contracts/ERC721/internal/util/ERC721TestBase.sol b/contracts/ERC721/internal/util/ERC721TestBase.sol index 869c4c9..7d15257 100644 --- a/contracts/ERC721/internal/util/ERC721TestBase.sol +++ b/contracts/ERC721/internal/util/ERC721TestBase.sol @@ -4,16 +4,17 @@ import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "../../../util/PropertiesConstants.sol"; import "../../../util/PropertiesHelper.sol"; +import {MockReceiver} from "./MockReceiver.sol"; abstract contract CryticERC721TestBase is ERC721, ERC721Enumerable, PropertiesAsserts, PropertiesConstants { // Is the contract allowed to change its total supply? bool isMintableOrBurnable; bool hasMaxSupply; + MockReceiver safeReceiver; + MockReceiver unsafeReceiver; - - // The following functions are overrides required by Solidity. - + // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal virtual diff --git a/contracts/ERC721/internal/util/MockReceiver.sol b/contracts/ERC721/internal/util/MockReceiver.sol new file mode 100644 index 0000000..618ac84 --- /dev/null +++ b/contracts/ERC721/internal/util/MockReceiver.sol @@ -0,0 +1,20 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + + +contract MockReceiver is ERC721Holder { + bool shouldReceive; + + constructor(bool _shouldReceive) { + shouldReceive = _shouldReceive; + } + + function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { + if (shouldReceive) { + return this.onERC721Received.selector; + } + + return bytes4(0); + } +} \ No newline at end of file diff --git a/contracts/ERC721/util/OZERC721.sol b/contracts/ERC721/util/OZERC721.sol deleted file mode 100644 index b84c750..0000000 --- a/contracts/ERC721/util/OZERC721.sol +++ /dev/null @@ -1,28 +0,0 @@ -pragma solidity ^0.8.13; - -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; - -contract OZERC721 is ERC721, ERC721Enumerable { - - constructor() ERC721("OZERC721","OZ") {} - - // The following functions are overrides required by Solidity. - function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) - internal - virtual - override(ERC721, ERC721Enumerable) - { - super._beforeTokenTransfer(from, to, tokenId, batchSize); - } - - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC721, ERC721Enumerable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} \ No newline at end of file From fee51716bdebf3bee22c40fc349ccb2b27511568 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Fri, 31 Mar 2023 17:29:16 +0200 Subject: [PATCH 07/23] working internal and external tests for properties, added readme --- contracts/ERC721/README.md | 87 ++- contracts/ERC721/external/echidna.config.yaml | 7 - .../ERC721ExternalBasicProperties.sol | 6 +- .../ERC721ExternalBurnableProperties.sol | 7 +- .../ERC721ExternalMintableProperties.sol | 7 +- .../test/standard/ERC721BasicTests.sol | 14 + .../test/standard/ERC721BurnableTests.sol | 14 + .../test/standard/ERC721CompliantTests.sol | 1 - .../test/standard/ERC721MintableTests.sol | 14 + .../external/util/ERC721IncorrectBasic.sol | 575 +++++++++++++++++ .../external/util/ERC721IncorrectBurnable.sol | 581 ++++++++++++++++++ .../external/util/ERC721IncorrectMintable.sol | 572 +++++++++++++++++ contracts/ERC721/internal/echidna.config.yaml | 6 - .../properties/ERC721BasicProperties.sol | 1 + .../properties/ERC721BurnableProperties.sol | 15 +- .../properties/ERC721MintableProperties.sol | 5 +- .../test/standard/ERC721BasicTests.sol} | 53 +- .../test/standard/ERC721BurnableTests.sol | 96 +++ ...ouldRevert.sol => ERC721MintableTests.sol} | 23 +- .../test/standard/ERC721NonCompliant.sol | 55 -- .../ERC721/internal/util/ERC721TestBase.sol | 1 + 21 files changed, 1984 insertions(+), 156 deletions(-) delete mode 100644 contracts/ERC721/external/echidna.config.yaml create mode 100644 contracts/ERC721/external/test/standard/ERC721BasicTests.sol create mode 100644 contracts/ERC721/external/test/standard/ERC721BurnableTests.sol create mode 100644 contracts/ERC721/external/test/standard/ERC721MintableTests.sol create mode 100644 contracts/ERC721/external/util/ERC721IncorrectBasic.sol create mode 100644 contracts/ERC721/external/util/ERC721IncorrectBurnable.sol create mode 100644 contracts/ERC721/external/util/ERC721IncorrectMintable.sol delete mode 100644 contracts/ERC721/internal/echidna.config.yaml rename contracts/ERC721/{external/test/standard/ERC721ShouldRevert.sol => internal/test/standard/ERC721BasicTests.sol} (67%) create mode 100644 contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol rename contracts/ERC721/internal/test/standard/{ERC721ShouldRevert.sol => ERC721MintableTests.sol} (81%) delete mode 100644 contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol diff --git a/contracts/ERC721/README.md b/contracts/ERC721/README.md index 9b9a48d..358a63b 100644 --- a/contracts/ERC721/README.md +++ b/contracts/ERC721/README.md @@ -7,7 +7,9 @@ - [Adding internal test methods to an ERC721](#adding-internal-test-methods-to-an-erc721) - [Developing](#developing) - [Properties Tested](#properties-tested) - - [Should revert](#should-revert) + - [Basic Properties](#basic-properties) + - [Mintable Properties](#mintable-properties) + - [Burnable Properties](#burnable-properties) ## Consuming @@ -19,20 +21,7 @@ Some properties of the ERC721 spec cannot be tested externally because testing t To compensate for this limitation, a vault under test may optionally implement a set of methods that allow such properties to be tested. See [IERC721Internal](util/IERC721Internal.sol) for the list of methods. -These methods should be added to the ERC721 contract by a derived, test-environment-only contract to minimize changes to the production contract. When an ERC721 under test implements IERC721Internal, pass `true` to the test harness's `initialize()` function to enable the properties that require the internal interface: - -``` -contract MyERC721 is IERC721Internal { ... } - -contract MyERC721Testable is MyERC721, IERC721Internal { ... } - -contract TestHarness is CryticERC721InternalPropertyTests{ - constructor(...) { - [...] - initialize(true); - } -} -``` +These methods should be added to the ERC721 contract by a derived, test-environment-only contract to minimize changes to the production contract. ## Developing @@ -40,37 +29,85 @@ Before doing any development, run `forge install` to get dependencies sorted out Running tests(used to validate the properties are working correctly): -- Internal: -`echidna-test ./contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol --contract TestHarness --config ./contracts/ERC721/internal/test/echidna.config.yaml` +### Basic properties + - External: -`echidna-test ./contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` +`echidna ./contracts/ERC721/external/test/standard/ERC721BasicTests.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` +- Internal: +`echidna ./contracts/ERC721/internal/test/standard/ERC721BasicTests.sol --contract TestHarness --config ./contracts/ERC721/internal/test/echidna.config.yaml` Should cause these properties to fail: +- test_ERC721_transferFromResetApproval +- test_ERC721_transferFromUpdatesOwner +- test_ERC721_transferFromSelf +- test_ERC721_transferFromSelfResetsApproval - test_ERC721_external_ownerOfInvalidTokenMustRevert - test_ERC721_external_balanceOfZeroAddressMustRevert - test_ERC721_external_approvingInvalidTokenMustRevert - test_ERC721_external_transferFromNotApproved - test_ERC721_external_transferFromZeroAddress -- test_ERC721_external_transferToZeroAddress +- test_ERC721_external_transferToZeroAddress - test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver +### Mintable properties +- External: +`echidna ./contracts/ERC721/external/test/standard/ERC721MintableTests.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` +- Internal: +`echidna ./contracts/ERC721/internal/test/standard/ERC721MintableTests.sol --contract TestHarness --config ./contracts/ERC721/internal/test/echidna.config.yaml` + +Should cause these properties to fail: +- test_ERC721_mintIncreasesSupply +- test_ERC721_mintCreatesFreshToken +### Burnable properties +- External: +`echidna ./contracts/ERC721/external/test/standard/ERC721BurnableTests.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` +- Internal: +`echidna ./contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol --contract TestHarness --config ./contracts/ERC721/internal/test/echidna.config.yaml` +Should cause these properties to fail: +- test_ERC721_burnReducesTotalSupply +- test_ERC721_burnRevertOnTransferFromPreviousOwner +- test_ERC721_burnRevertOnApprove +- test_ERC721_burnRevertOnOwnerOf +- test_ERC721_burnRevertOnTransferFromZeroAddress +- test_ERC721_burnRevertOnGetApproved -Run property tests against vanilla OpenZeppelin ERC721: +### Vanilla OpenZeppelin ERC721 - Internal: -`echidna-test ./contracts/ERC721/internal/test/standard/ERC721Compliant.sol --contract ERC721Compliant --config ./contracts/ERC721/internal/test/echidna.config.yaml` +`echidna ./contracts/ERC721/internal/test/standard/ERC721Compliant.sol --contract ERC721Compliant --config ./contracts/ERC721/internal/test/echidna.config.yaml` - External: -`echidna-test ./contracts/ERC721/external/test/standard/ERC721CompliantTests.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` +`echidna ./contracts/ERC721/external/test/standard/ERC721CompliantTests.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` [EIP-721 Spec](https://eips.ethereum.org/EIPS/eip-721) ## Properties Tested -### Should revert -- `ownerOf()` must revert for the zero address -- `safeTransferFrom()` must revert if the receiver does not implement onERC721Received \ No newline at end of file +### Basic properties +- test_ERC721_transferFromResetApproval +- test_ERC721_transferFromUpdatesOwner +- test_ERC721_transferFromSelf +- test_ERC721_transferFromSelfResetsApproval +- test_ERC721_external_ownerOfInvalidTokenMustRevert +- test_ERC721_external_balanceOfZeroAddressMustRevert +- test_ERC721_external_approvingInvalidTokenMustRevert +- test_ERC721_external_transferFromNotApproved +- test_ERC721_external_transferFromZeroAddress +- test_ERC721_external_transferToZeroAddress +- test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver + +### Mintable properties +- test_ERC721_mintIncreasesSupply +- test_ERC721_mintCreatesFreshToken + +### Burnable properties +- test_ERC721_burnReducesTotalSupply +- test_ERC721_burnRevertOnTransferFromPreviousOwner +- test_ERC721_burnRevertOnApprove +- test_ERC721_burnRevertOnOwnerOf +- test_ERC721_burnRevertOnTransferFromZeroAddress +- test_ERC721_burnRevertOnGetApproved \ No newline at end of file diff --git a/contracts/ERC721/external/echidna.config.yaml b/contracts/ERC721/external/echidna.config.yaml deleted file mode 100644 index 4603034..0000000 --- a/contracts/ERC721/external/echidna.config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -coverage: true -multi-abi: true -corpusDir: "corpus" -testMode: assertion -testLimit: 100000 -deployer: "0x10000" -sender: ["0x10000", "0x20000", "0x30000"] \ No newline at end of file diff --git a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol index a948399..29207b3 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol @@ -5,9 +5,6 @@ import "../util/ERC721ExternalTestBase.sol"; abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTestBase { using Address for address; - constructor() { - } - //////////////////////////////////////// // Properties @@ -26,7 +23,6 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes // Approving an invalid token should throw function test_ERC721_external_approvingInvalidTokenMustRevert() public virtual { token.approve(address(0), type(uint256).max); - assertWithMsg(false, "Breakpoint"); assertWithMsg(false, "Approving an invalid token should have reverted"); } @@ -93,7 +89,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes token.transferFrom(msg.sender, address(0), tokenId); - assertWithMsg(token.ownerOf(tokenId) == address(0), "Transfer to zero address should have reverted"); + assertWithMsg(false, "Transfer to zero address should have reverted"); } // Transfers to self should not break accounting diff --git a/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol index 0d3e4f8..8bc2000 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol @@ -4,20 +4,17 @@ import "../util/ERC721ExternalTestBase.sol"; abstract contract CryticERC721ExternalBurnableProperties is CryticERC721ExternalTestBase { using Address for address; - - constructor() { - } - //////////////////////////////////////// // Properties // The burn function should destroy tokens and reduce the total supply - function test_ERC721_external_burnReducesTotalSupply(uint256 tokenId) public virtual { + function test_ERC721_external_burnReducesTotalSupply() public virtual { require(token.isMintableOrBurnable()); uint256 selfBalance = token.balanceOf(msg.sender); require(selfBalance > 0); uint256 oldTotalSupply = token.totalSupply(); + for(uint256 i; i < selfBalance; i++) { uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); token.burn(tokenId); diff --git a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol index 67687e0..0fece1e 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol @@ -4,10 +4,7 @@ import "../util/ERC721ExternalTestBase.sol"; abstract contract CryticERC721ExternalMintableProperties is CryticERC721ExternalTestBase { using Address for address; - - constructor() { - } - + mapping (uint256 => bool) usedId; //////////////////////////////////////// // Properties // mint increases the total supply @@ -33,6 +30,8 @@ abstract contract CryticERC721ExternalMintableProperties is CryticERC721External for(uint256 i = selfBalance; i < endIndex; i++) { uint256 tokenId = token.tokenOfOwnerByIndex(address(this), i); assertWithMsg(token.ownerOf(tokenId) == address(this), "Token ID was not minted to receiver"); + assertWithMsg(!usedId[tokenId], "Token ID minted is not new"); + usedId[tokenId] = true; } assertEq(selfBalance + amount, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); diff --git a/contracts/ERC721/external/test/standard/ERC721BasicTests.sol b/contracts/ERC721/external/test/standard/ERC721BasicTests.sol new file mode 100644 index 0000000..14caa5b --- /dev/null +++ b/contracts/ERC721/external/test/standard/ERC721BasicTests.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.8.0; + +import {CryticERC721ExternalBasicProperties} from "../../properties/ERC721ExternalBasicProperties.sol"; +import {ERC721IncorrectBasic} from "../../util/ERC721IncorrectBasic.sol"; +import {IERC721Internal} from "../../../util/IERC721Internal.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; + +contract TestHarness is CryticERC721ExternalBasicProperties { + constructor() { + token = IERC721Internal(address(new ERC721IncorrectBasic("ERC721BAD","ERC721BAD"))); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); + } +} \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721BurnableTests.sol b/contracts/ERC721/external/test/standard/ERC721BurnableTests.sol new file mode 100644 index 0000000..a19b98d --- /dev/null +++ b/contracts/ERC721/external/test/standard/ERC721BurnableTests.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.8.0; + +import {CryticERC721ExternalBurnableProperties} from "../../properties/ERC721ExternalBurnableProperties.sol"; +import {ERC721IncorrectBurnable} from "../../util/ERC721IncorrectBurnable.sol"; +import {IERC721Internal} from "../../../util/IERC721Internal.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; + +contract TestHarness is CryticERC721ExternalBurnableProperties { + constructor() { + token = IERC721Internal(address(new ERC721IncorrectBurnable("ERC721BAD","ERC721BAD"))); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); + } +} \ No newline at end of file diff --git a/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol b/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol index 3116d55..9030ef6 100644 --- a/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol +++ b/contracts/ERC721/external/test/standard/ERC721CompliantTests.sol @@ -6,7 +6,6 @@ import {IERC721Internal} from "../../../util/IERC721Internal.sol"; import {MockReceiver} from "../../util/MockReceiver.sol"; contract TestHarness is CryticERC721ExternalPropertyTests { - constructor() { token = IERC721Internal(address(new ERC721Compliant())); mockSafeReceiver = new MockReceiver(true); diff --git a/contracts/ERC721/external/test/standard/ERC721MintableTests.sol b/contracts/ERC721/external/test/standard/ERC721MintableTests.sol new file mode 100644 index 0000000..6fb16a5 --- /dev/null +++ b/contracts/ERC721/external/test/standard/ERC721MintableTests.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.8.0; + +import {CryticERC721ExternalMintableProperties} from "../../properties/ERC721ExternalMintableProperties.sol"; +import {ERC721IncorrectMintable} from "../../util/ERC721IncorrectMintable.sol"; +import {IERC721Internal} from "../../../util/IERC721Internal.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; + +contract TestHarness is CryticERC721ExternalMintableProperties { + constructor() { + token = IERC721Internal(address(new ERC721IncorrectMintable("ERC721BAD","ERC721BAD"))); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); + } +} \ No newline at end of file diff --git a/contracts/ERC721/external/util/ERC721IncorrectBasic.sol b/contracts/ERC721/external/util/ERC721IncorrectBasic.sol new file mode 100644 index 0000000..8bcf84e --- /dev/null +++ b/contracts/ERC721/external/util/ERC721IncorrectBasic.sol @@ -0,0 +1,575 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/Context.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +/** + * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including + * the Metadata extension, but not including the Enumerable extension, which is available separately as + * {ERC721Enumerable}. + */ +contract ERC721IncorrectBasic is Context, ERC165, IERC721, IERC721Metadata { + using Address for address; + using Strings for uint256; + + // Token name + string private _name; + + // Token symbol + string private _symbol; + + uint256 public maxSupply; + uint256 public counter; + bool public isMintableOrBurnable; + address excluded = address(0x10000); + + // Mapping from token ID to owner address + mapping(uint256 => address) private _owners; + + // Mapping owner address to token count + mapping(address => uint256) private _balances; + + // Mapping from token ID to approved address + mapping(uint256 => address) private _tokenApprovals; + + // Mapping from owner to operator approvals + mapping(address => mapping(address => bool)) private _operatorApprovals; + + // Mapping from owner to list of owned token IDs + mapping(address => mapping(uint256 => uint256)) private _ownedTokens; + + // Mapping from token ID to index of the owner tokens list + mapping(uint256 => uint256) private _ownedTokensIndex; + + // Array with all token ids, used for enumeration + uint256[] private _allTokens; + + // Mapping from token id to position in the allTokens array + mapping(uint256 => uint256) private _allTokensIndex; + + /** + * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + maxSupply = 100; + isMintableOrBurnable = true; + } + + function mint(address to, uint256 amount) public { + for(uint256 i; i < amount; i++) { + _mint(to, counter++); + } + } + + function _customMint(address to, uint256 amount) external { + mint(to, amount); + } + + function _customMaxSupply() external view returns (uint256) { + return maxSupply; + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { + return + interfaceId == type(IERC721).interfaceId || + interfaceId == type(IERC721Metadata).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @dev See {IERC721-balanceOf}. + */ + function balanceOf(address owner) public view virtual override returns (uint256) { + //require(owner != address(0), "ERC721: address zero is not a valid owner"); + return _balances[owner]; + } + + /** + * @dev See {IERC721-ownerOf}. + */ + function ownerOf(uint256 tokenId) public view virtual override returns (address) { + address owner = _ownerOf(tokenId); + //require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + /** + * @dev See {IERC721Metadata-name}. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev See {IERC721Metadata-symbol}. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev See {IERC721Metadata-tokenURI}. + */ + function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { + _requireMinted(tokenId); + + string memory baseURI = _baseURI(); + return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; + } + + /** + * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each + * token will be the concatenation of the `baseURI` and the `tokenId`. Empty + * by default, can be overridden in child contracts. + */ + function _baseURI() internal view virtual returns (string memory) { + return ""; + } + + /** + * @dev See {IERC721-approve}. + */ + function approve(address to, uint256 tokenId) public virtual override { + if (_exists(tokenId)){ + address owner = ERC721IncorrectBasic.ownerOf(tokenId); + require(to != owner, "ERC721: approval to current owner"); + + require( + _msgSender() == owner || isApprovedForAll(owner, _msgSender()), + "ERC721: approve caller is not token owner or approved for all" + ); + + _approve(to, tokenId); + } + } + + /** + * @dev See {IERC721-getApproved}. + */ + function getApproved(uint256 tokenId) public view virtual override returns (address) { + //_requireMinted(tokenId); + + return _tokenApprovals[tokenId]; + } + + /** + * @dev See {IERC721-setApprovalForAll}. + */ + function setApprovalForAll(address operator, bool approved) public virtual override { + _setApprovalForAll(_msgSender(), operator, approved); + } + + /** + * @dev See {IERC721-isApprovedForAll}. + */ + function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { + return _operatorApprovals[owner][operator]; + } + + /** + * @dev See {IERC721-transferFrom}. + */ + function transferFrom(address from, address to, uint256 tokenId) public virtual override { + //solhint-disable-next-line max-line-length + //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + + _transfer(from, to, tokenId); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { + safeTransferFrom(from, to, tokenId, ""); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { + //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + _safeTransfer(from, to, tokenId, data); + } + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * `data` is additional data, it has no specified format and it is sent in call to `to`. + * + * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. + * implement alternative mechanisms to perform token transfer, such as signature-based. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { + _transfer(from, to, tokenId); + //require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); + } + + /** + * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist + */ + function _ownerOf(uint256 tokenId) internal view virtual returns (address) { + return _owners[tokenId]; + } + + /** + * @dev Returns whether `tokenId` exists. + * + * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. + * + * Tokens start existing when they are minted (`_mint`), + * and stop existing when they are burned (`_burn`). + */ + function _exists(uint256 tokenId) internal view virtual returns (bool) { + return _ownerOf(tokenId) != address(0); + } + + /** + * @dev Returns whether `spender` is allowed to manage `tokenId`. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { + address owner = ERC721IncorrectBasic.ownerOf(tokenId); + return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); + } + + /** + * @dev Safely mints `tokenId` and transfers it to `to`. + * + * Requirements: + * + * - `tokenId` must not exist. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeMint(address to, uint256 tokenId) internal virtual { + _safeMint(to, tokenId, ""); + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { + _mint(to, tokenId); + /* require( + _checkOnERC721Received(address(0), to, tokenId, data), + "ERC721: transfer to non ERC721Receiver implementer" + ); */ + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mint(address to, uint256 tokenId) internal virtual { + require(to != address(0), "ERC721: mint to the zero address"); + require(!_exists(tokenId), "ERC721: token already minted"); + + _beforeTokenTransfer(address(0), to, tokenId, 1); + + // Check that tokenId was not minted by `_beforeTokenTransfer` hook + require(!_exists(tokenId), "ERC721: token already minted"); + + unchecked { + // Will not overflow unless all 2**256 token ids are minted to the same owner. + // Given that tokens are minted one by one, it is impossible in practice that + // this ever happens. Might change if we allow batch minting. + // The ERC fails to describe this case. + _balances[to] += 1; + } + + _owners[tokenId] = to; + + emit Transfer(address(0), to, tokenId); + + _afterTokenTransfer(address(0), to, tokenId, 1); + } + + /** + * @dev Destroys `tokenId`. + * The approval is cleared when the token is burned. + * This is an internal function that does not check if the sender is authorized to operate on the token. + * + * Requirements: + * + * - `tokenId` must exist. + * + * Emits a {Transfer} event. + */ + function _burn(uint256 tokenId) internal virtual { + address owner = ERC721IncorrectBasic.ownerOf(tokenId); + + _beforeTokenTransfer(owner, address(0), tokenId, 1); + + // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook + owner = ERC721IncorrectBasic.ownerOf(tokenId); + + // Clear approvals + //delete _tokenApprovals[tokenId]; + + unchecked { + // Cannot overflow, as that would require more tokens to be burned/transferred + // out than the owner initially received through minting and transferring in. + _balances[owner] -= 1; + } + delete _owners[tokenId]; + + emit Transfer(owner, address(0), tokenId); + + _afterTokenTransfer(owner, address(0), tokenId, 1); + } + + /** + * @dev Transfers `tokenId` from `from` to `to`. + * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * + * Emits a {Transfer} event. + */ + function _transfer(address from, address to, uint256 tokenId) internal virtual { + if (from == excluded) { + // Do nothing + } else if (from == address(0)) { + _mint(to, tokenId); + } else { + require(ERC721IncorrectBasic.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); + //require(to != address(0), "ERC721: transfer to the zero address"); + + _beforeTokenTransfer(from, to, tokenId, 1); + + // Check that tokenId was not transferred by `_beforeTokenTransfer` hook + require(ERC721IncorrectBasic.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); + + // Clear approvals from the previous owner + //delete _tokenApprovals[tokenId]; + uint256 balanceFrom = _balances[from] - 1; + uint256 balanceTo = _balances[to] + 1; + + _balances[from] = balanceFrom; + _balances[to] = balanceTo; + + _owners[tokenId] = to; + + emit Transfer(from, to, tokenId); + + _afterTokenTransfer(from, to, tokenId, 1); + } + + } + + /** + * @dev Approve `to` to operate on `tokenId` + * + * Emits an {Approval} event. + */ + function _approve(address to, uint256 tokenId) internal virtual { + _tokenApprovals[tokenId] = to; + emit Approval(ERC721IncorrectBasic.ownerOf(tokenId), to, tokenId); + } + + /** + * @dev Approve `operator` to operate on all of `owner` tokens + * + * Emits an {ApprovalForAll} event. + */ + function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { + require(owner != operator, "ERC721: approve to caller"); + _operatorApprovals[owner][operator] = approved; + emit ApprovalForAll(owner, operator, approved); + } + + /** + * @dev Reverts if the `tokenId` has not been minted yet. + */ + function _requireMinted(uint256 tokenId) internal view virtual { + require(_exists(tokenId), "ERC721: invalid token ID"); + } + + + /** + * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is + * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. + * + * Calling conditions: + * + * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. + * - When `from` is zero, the tokens were minted for `to`. + * - When `to` is zero, ``from``'s tokens were burned. + * - `from` and `to` are never both zero. + * - `batchSize` is non-zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} + + /** + * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) { + require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); + return _ownedTokens[owner][index]; + } + + /** + * @dev See {IERC721Enumerable-totalSupply}. + */ + function totalSupply() public view virtual returns (uint256) { + return _allTokens.length; + } + + /** + * @dev See {IERC721Enumerable-tokenByIndex}. + */ + function tokenByIndex(uint256 index) public view virtual returns (uint256) { + require(index < totalSupply(), "ERC721Enumerable: global index out of bounds"); + return _allTokens[index]; + } + + /** + * @dev See {ERC721-_beforeTokenTransfer}. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 firstTokenId, + uint256 batchSize + ) internal virtual { + if (batchSize > 1) { + if (from != address(0)) { + _balances[from] -= batchSize; + } + if (to != address(0)) { + _balances[to] += batchSize; + } + } + + if (batchSize > 1) { + // Will only trigger during construction. Batch transferring (minting) is not available afterwards. + revert("ERC721Enumerable: consecutive transfers not supported"); + } + + uint256 tokenId = firstTokenId; + + if (from == address(0)) { + _addTokenToAllTokensEnumeration(tokenId); + } else if (from != to) { + _removeTokenFromOwnerEnumeration(from, tokenId); + } + if (to == address(0)) { + _removeTokenFromAllTokensEnumeration(tokenId); + } else if (to != from) { + _addTokenToOwnerEnumeration(to, tokenId); + } + } + + /** + * @dev Private function to add a token to this extension's ownership-tracking data structures. + * @param to address representing the new owner of the given token ID + * @param tokenId uint256 ID of the token to be added to the tokens list of the given address + */ + function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { + uint256 length = balanceOf(to); + _ownedTokens[to][length] = tokenId; + _ownedTokensIndex[tokenId] = length; + } + + /** + * @dev Private function to add a token to this extension's token tracking data structures. + * @param tokenId uint256 ID of the token to be added to the tokens list + */ + function _addTokenToAllTokensEnumeration(uint256 tokenId) private { + _allTokensIndex[tokenId] = _allTokens.length; + _allTokens.push(tokenId); + } + + /** + * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that + * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for + * gas optimizations e.g. when performing a transfer operation (avoiding double writes). + * This has O(1) time complexity, but alters the order of the _ownedTokens array. + * @param from address representing the previous owner of the given token ID + * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address + */ + function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { + // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = balanceOf(from) - 1; + uint256 tokenIndex = _ownedTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary + if (tokenIndex != lastTokenIndex) { + uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; + + _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + } + + // This also deletes the contents at the last position of the array + delete _ownedTokensIndex[tokenId]; + delete _ownedTokens[from][lastTokenIndex]; + } + + /** + * @dev Private function to remove a token from this extension's token tracking data structures. + * This has O(1) time complexity, but alters the order of the _allTokens array. + * @param tokenId uint256 ID of the token to be removed from the tokens list + */ + function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { + // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = _allTokens.length - 1; + uint256 tokenIndex = _allTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so + // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding + // an 'if' statement (like in _removeTokenFromOwnerEnumeration) + uint256 lastTokenId = _allTokens[lastTokenIndex]; + + _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + + // This also deletes the contents at the last position of the array + delete _allTokensIndex[tokenId]; + _allTokens.pop(); + } +} diff --git a/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol b/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol new file mode 100644 index 0000000..2dd8d59 --- /dev/null +++ b/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/Context.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +/** + * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including + * the Metadata extension, but not including the Enumerable extension, which is available separately as + * {ERC721Enumerable}. + */ +contract ERC721IncorrectBurnable is Context, ERC165, IERC721, IERC721Metadata { + using Address for address; + using Strings for uint256; + + // Token name + string private _name; + + // Token symbol + string private _symbol; + + uint256 public maxSupply; + uint256 public counter; + bool public isMintableOrBurnable; + address excluded = address(0x10000); + + // Mapping from token ID to owner address + mapping(uint256 => address) private _owners; + + // Mapping owner address to token count + mapping(address => uint256) private _balances; + + // Mapping from token ID to approved address + mapping(uint256 => address) private _tokenApprovals; + + // Mapping from owner to operator approvals + mapping(address => mapping(address => bool)) private _operatorApprovals; + + // Mapping from owner to list of owned token IDs + mapping(address => mapping(uint256 => uint256)) private _ownedTokens; + + // Mapping from token ID to index of the owner tokens list + mapping(uint256 => uint256) private _ownedTokensIndex; + + // Array with all token ids, used for enumeration + uint256[] private _allTokens; + + // Mapping from token id to position in the allTokens array + mapping(uint256 => uint256) private _allTokensIndex; + + /** + * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + maxSupply = 100; + isMintableOrBurnable = true; + } + + function mint(address to, uint256 amount) public { + for(uint256 i; i < amount; i++) { + _mint(to, counter++); + } + } + + function burn(uint256 tokenId) public virtual { + //solhint-disable-next-line max-line-length + require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + _burn(tokenId); + } + + function _customMint(address to, uint256 amount) external { + mint(to, amount); + } + + function _customMaxSupply() external view returns (uint256) { + return maxSupply; + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { + return + interfaceId == type(IERC721).interfaceId || + interfaceId == type(IERC721Metadata).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @dev See {IERC721-balanceOf}. + */ + function balanceOf(address owner) public view virtual override returns (uint256) { + //require(owner != address(0), "ERC721: address zero is not a valid owner"); + return _balances[owner]; + } + + /** + * @dev See {IERC721-ownerOf}. + */ + function ownerOf(uint256 tokenId) public view virtual override returns (address) { + address owner = _ownerOf(tokenId); + //require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + /** + * @dev See {IERC721Metadata-name}. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev See {IERC721Metadata-symbol}. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev See {IERC721Metadata-tokenURI}. + */ + function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { + _requireMinted(tokenId); + + string memory baseURI = _baseURI(); + return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; + } + + /** + * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each + * token will be the concatenation of the `baseURI` and the `tokenId`. Empty + * by default, can be overridden in child contracts. + */ + function _baseURI() internal view virtual returns (string memory) { + return ""; + } + + /** + * @dev See {IERC721-approve}. + */ + function approve(address to, uint256 tokenId) public virtual override { + if (_exists(tokenId)){ + address owner = ERC721IncorrectBurnable.ownerOf(tokenId); + require(to != owner, "ERC721: approval to current owner"); + + require( + _msgSender() == owner || isApprovedForAll(owner, _msgSender()), + "ERC721: approve caller is not token owner or approved for all" + ); + + _approve(to, tokenId); + } + } + + /** + * @dev See {IERC721-getApproved}. + */ + function getApproved(uint256 tokenId) public view virtual override returns (address) { + //_requireMinted(tokenId); + + return _tokenApprovals[tokenId]; + } + + /** + * @dev See {IERC721-setApprovalForAll}. + */ + function setApprovalForAll(address operator, bool approved) public virtual override { + _setApprovalForAll(_msgSender(), operator, approved); + } + + /** + * @dev See {IERC721-isApprovedForAll}. + */ + function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { + return _operatorApprovals[owner][operator]; + } + + /** + * @dev See {IERC721-transferFrom}. + */ + function transferFrom(address from, address to, uint256 tokenId) public virtual override { + //solhint-disable-next-line max-line-length + //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + + _transfer(from, to, tokenId); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { + safeTransferFrom(from, to, tokenId, ""); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { + //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + _safeTransfer(from, to, tokenId, data); + } + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * `data` is additional data, it has no specified format and it is sent in call to `to`. + * + * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. + * implement alternative mechanisms to perform token transfer, such as signature-based. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { + _transfer(from, to, tokenId); + //require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); + } + + /** + * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist + */ + function _ownerOf(uint256 tokenId) internal view virtual returns (address) { + return _owners[tokenId]; + } + + /** + * @dev Returns whether `tokenId` exists. + * + * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. + * + * Tokens start existing when they are minted (`_mint`), + * and stop existing when they are burned (`_burn`). + */ + function _exists(uint256 tokenId) internal view virtual returns (bool) { + return _ownerOf(tokenId) != address(0); + } + + /** + * @dev Returns whether `spender` is allowed to manage `tokenId`. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { + address owner = ERC721IncorrectBurnable.ownerOf(tokenId); + return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); + } + + /** + * @dev Safely mints `tokenId` and transfers it to `to`. + * + * Requirements: + * + * - `tokenId` must not exist. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeMint(address to, uint256 tokenId) internal virtual { + _safeMint(to, tokenId, ""); + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { + _mint(to, tokenId); + /* require( + _checkOnERC721Received(address(0), to, tokenId, data), + "ERC721: transfer to non ERC721Receiver implementer" + ); */ + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mint(address to, uint256 tokenId) internal virtual { + require(to != address(0), "ERC721: mint to the zero address"); + require(!_exists(tokenId), "ERC721: token already minted"); + + _beforeTokenTransfer(address(0), to, tokenId, 1); + + // Check that tokenId was not minted by `_beforeTokenTransfer` hook + require(!_exists(tokenId), "ERC721: token already minted"); + + unchecked { + // Will not overflow unless all 2**256 token ids are minted to the same owner. + // Given that tokens are minted one by one, it is impossible in practice that + // this ever happens. Might change if we allow batch minting. + // The ERC fails to describe this case. + _balances[to] += 1; + } + + _owners[tokenId] = to; + + emit Transfer(address(0), to, tokenId); + + _afterTokenTransfer(address(0), to, tokenId, 1); + } + + /** + * @dev Destroys `tokenId`. + * The approval is cleared when the token is burned. + * This is an internal function that does not check if the sender is authorized to operate on the token. + * + * Requirements: + * + * - `tokenId` must exist. + * + * Emits a {Transfer} event. + */ + function _burn(uint256 tokenId) internal virtual { + address owner = ERC721IncorrectBurnable.ownerOf(tokenId); + + _beforeTokenTransfer(owner, address(0), tokenId, 1); + + // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook + owner = ERC721IncorrectBurnable.ownerOf(tokenId); + + // Clear approvals + //delete _tokenApprovals[tokenId]; + + unchecked { + // Cannot overflow, as that would require more tokens to be burned/transferred + // out than the owner initially received through minting and transferring in. + _balances[owner] -= 1; + } + //delete _owners[tokenId]; + + emit Transfer(owner, address(0), tokenId); + + _afterTokenTransfer(owner, address(0), tokenId, 1); + } + + /** + * @dev Transfers `tokenId` from `from` to `to`. + * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * + * Emits a {Transfer} event. + */ + function _transfer(address from, address to, uint256 tokenId) internal virtual { + if (from == excluded) { + // Do nothing + } else if (from == address(0)) { + _mint(to, tokenId); + } else { + require(ERC721IncorrectBurnable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); + //require(to != address(0), "ERC721: transfer to the zero address"); + + _beforeTokenTransfer(from, to, tokenId, 1); + + // Check that tokenId was not transferred by `_beforeTokenTransfer` hook + require(ERC721IncorrectBurnable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); + + // Clear approvals from the previous owner + //delete _tokenApprovals[tokenId]; + uint256 balanceFrom = _balances[from] - 1; + uint256 balanceTo = _balances[to] + 1; + + _balances[from] = balanceFrom; + _balances[to] = balanceTo; + + _owners[tokenId] = to; + + emit Transfer(from, to, tokenId); + + _afterTokenTransfer(from, to, tokenId, 1); + } + + } + + /** + * @dev Approve `to` to operate on `tokenId` + * + * Emits an {Approval} event. + */ + function _approve(address to, uint256 tokenId) internal virtual { + _tokenApprovals[tokenId] = to; + emit Approval(ERC721IncorrectBurnable.ownerOf(tokenId), to, tokenId); + } + + /** + * @dev Approve `operator` to operate on all of `owner` tokens + * + * Emits an {ApprovalForAll} event. + */ + function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { + require(owner != operator, "ERC721: approve to caller"); + _operatorApprovals[owner][operator] = approved; + emit ApprovalForAll(owner, operator, approved); + } + + /** + * @dev Reverts if the `tokenId` has not been minted yet. + */ + function _requireMinted(uint256 tokenId) internal view virtual { + require(_exists(tokenId), "ERC721: invalid token ID"); + } + + + /** + * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is + * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. + * + * Calling conditions: + * + * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. + * - When `from` is zero, the tokens were minted for `to`. + * - When `to` is zero, ``from``'s tokens were burned. + * - `from` and `to` are never both zero. + * - `batchSize` is non-zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} + + /** + * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) { + require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); + return _ownedTokens[owner][index]; + } + + /** + * @dev See {IERC721Enumerable-totalSupply}. + */ + function totalSupply() public view virtual returns (uint256) { + return _allTokens.length; + } + + /** + * @dev See {IERC721Enumerable-tokenByIndex}. + */ + function tokenByIndex(uint256 index) public view virtual returns (uint256) { + require(index < totalSupply(), "ERC721Enumerable: global index out of bounds"); + return _allTokens[index]; + } + + /** + * @dev See {ERC721-_beforeTokenTransfer}. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 firstTokenId, + uint256 batchSize + ) internal virtual { + if (batchSize > 1) { + if (from != address(0)) { + _balances[from] -= batchSize; + } + if (to != address(0)) { + _balances[to] += batchSize; + } + } + + if (batchSize > 1) { + // Will only trigger during construction. Batch transferring (minting) is not available afterwards. + revert("ERC721Enumerable: consecutive transfers not supported"); + } + + uint256 tokenId = firstTokenId; + + if (from == address(0)) { + _addTokenToAllTokensEnumeration(tokenId); + } else if (from != to) { + _removeTokenFromOwnerEnumeration(from, tokenId); + } + if (to == address(0)) { + //_removeTokenFromAllTokensEnumeration(tokenId); + } else if (to != from) { + _addTokenToOwnerEnumeration(to, tokenId); + } + } + + /** + * @dev Private function to add a token to this extension's ownership-tracking data structures. + * @param to address representing the new owner of the given token ID + * @param tokenId uint256 ID of the token to be added to the tokens list of the given address + */ + function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { + uint256 length = balanceOf(to); + _ownedTokens[to][length] = tokenId; + _ownedTokensIndex[tokenId] = length; + } + + /** + * @dev Private function to add a token to this extension's token tracking data structures. + * @param tokenId uint256 ID of the token to be added to the tokens list + */ + function _addTokenToAllTokensEnumeration(uint256 tokenId) private { + _allTokensIndex[tokenId] = _allTokens.length; + _allTokens.push(tokenId); + } + + /** + * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that + * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for + * gas optimizations e.g. when performing a transfer operation (avoiding double writes). + * This has O(1) time complexity, but alters the order of the _ownedTokens array. + * @param from address representing the previous owner of the given token ID + * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address + */ + function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { + // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = balanceOf(from) - 1; + uint256 tokenIndex = _ownedTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary + if (tokenIndex != lastTokenIndex) { + uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; + + _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + } + + // This also deletes the contents at the last position of the array + delete _ownedTokensIndex[tokenId]; + delete _ownedTokens[from][lastTokenIndex]; + } + + /** + * @dev Private function to remove a token from this extension's token tracking data structures. + * This has O(1) time complexity, but alters the order of the _allTokens array. + * @param tokenId uint256 ID of the token to be removed from the tokens list + */ + function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { + // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = _allTokens.length - 1; + uint256 tokenIndex = _allTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so + // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding + // an 'if' statement (like in _removeTokenFromOwnerEnumeration) + uint256 lastTokenId = _allTokens[lastTokenIndex]; + + _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + + // This also deletes the contents at the last position of the array + delete _allTokensIndex[tokenId]; + _allTokens.pop(); + } +} diff --git a/contracts/ERC721/external/util/ERC721IncorrectMintable.sol b/contracts/ERC721/external/util/ERC721IncorrectMintable.sol new file mode 100644 index 0000000..ffa4ea3 --- /dev/null +++ b/contracts/ERC721/external/util/ERC721IncorrectMintable.sol @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/Context.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; +import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +/** + * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including + * the Metadata extension, but not including the Enumerable extension, which is available separately as + * {ERC721Enumerable}. + */ +contract ERC721IncorrectMintable is Context, ERC165, IERC721, IERC721Metadata { + using Address for address; + using Strings for uint256; + + // Token name + string private _name; + + // Token symbol + string private _symbol; + + uint256 public maxSupply; + uint256 public counter; + bool public isMintableOrBurnable; + address excluded = address(0x10000); + + // Mapping from token ID to owner address + mapping(uint256 => address) private _owners; + + // Mapping owner address to token count + mapping(address => uint256) private _balances; + + // Mapping from token ID to approved address + mapping(uint256 => address) private _tokenApprovals; + + // Mapping from owner to operator approvals + mapping(address => mapping(address => bool)) private _operatorApprovals; + + // Mapping from owner to list of owned token IDs + mapping(address => mapping(uint256 => uint256)) private _ownedTokens; + + // Mapping from token ID to index of the owner tokens list + mapping(uint256 => uint256) private _ownedTokensIndex; + + // Array with all token ids, used for enumeration + uint256[] private _allTokens; + + // Mapping from token id to position in the allTokens array + mapping(uint256 => uint256) private _allTokensIndex; + + /** + * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + maxSupply = 100; + isMintableOrBurnable = true; + } + + function mint(address to, uint256 amount) public { + for(uint256 i; i < amount; i++) { + _mint(to, counter++); + } + } + + function _customMint(address to, uint256 amount) external { + mint(to, amount); + } + + function _customMaxSupply() external view returns (uint256) { + return maxSupply; + } + + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { + return + interfaceId == type(IERC721).interfaceId || + interfaceId == type(IERC721Metadata).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @dev See {IERC721-balanceOf}. + */ + function balanceOf(address owner) public view virtual override returns (uint256) { + require(owner != address(0), "ERC721: address zero is not a valid owner"); + return _balances[owner]; + } + + /** + * @dev See {IERC721-ownerOf}. + */ + function ownerOf(uint256 tokenId) public view virtual override returns (address) { + address owner = _ownerOf(tokenId); + require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + /** + * @dev See {IERC721Metadata-name}. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev See {IERC721Metadata-symbol}. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev See {IERC721Metadata-tokenURI}. + */ + function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { + _requireMinted(tokenId); + + string memory baseURI = _baseURI(); + return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; + } + + /** + * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each + * token will be the concatenation of the `baseURI` and the `tokenId`. Empty + * by default, can be overridden in child contracts. + */ + function _baseURI() internal view virtual returns (string memory) { + return ""; + } + + /** + * @dev See {IERC721-approve}. + */ + function approve(address to, uint256 tokenId) public virtual override { + + address owner = ERC721IncorrectMintable.ownerOf(tokenId); + require(to != owner, "ERC721: approval to current owner"); + + require( + _msgSender() == owner || isApprovedForAll(owner, _msgSender()), + "ERC721: approve caller is not token owner or approved for all" + ); + + _approve(to, tokenId); + + } + + /** + * @dev See {IERC721-getApproved}. + */ + function getApproved(uint256 tokenId) public view virtual override returns (address) { + _requireMinted(tokenId); + + return _tokenApprovals[tokenId]; + } + + /** + * @dev See {IERC721-setApprovalForAll}. + */ + function setApprovalForAll(address operator, bool approved) public virtual override { + _setApprovalForAll(_msgSender(), operator, approved); + } + + /** + * @dev See {IERC721-isApprovedForAll}. + */ + function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { + return _operatorApprovals[owner][operator]; + } + + /** + * @dev See {IERC721-transferFrom}. + */ + function transferFrom(address from, address to, uint256 tokenId) public virtual override { + //solhint-disable-next-line max-line-length + require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + + _transfer(from, to, tokenId); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { + safeTransferFrom(from, to, tokenId, ""); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { + require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + _safeTransfer(from, to, tokenId, data); + } + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * `data` is additional data, it has no specified format and it is sent in call to `to`. + * + * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. + * implement alternative mechanisms to perform token transfer, such as signature-based. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { + _transfer(from, to, tokenId); + //require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); + } + + /** + * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist + */ + function _ownerOf(uint256 tokenId) internal view virtual returns (address) { + return _owners[tokenId]; + } + + /** + * @dev Returns whether `tokenId` exists. + * + * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. + * + * Tokens start existing when they are minted (`_mint`), + * and stop existing when they are burned (`_burn`). + */ + function _exists(uint256 tokenId) internal view virtual returns (bool) { + return _ownerOf(tokenId) != address(0); + } + + /** + * @dev Returns whether `spender` is allowed to manage `tokenId`. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { + address owner = ERC721IncorrectMintable.ownerOf(tokenId); + return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); + } + + /** + * @dev Safely mints `tokenId` and transfers it to `to`. + * + * Requirements: + * + * - `tokenId` must not exist. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeMint(address to, uint256 tokenId) internal virtual { + _safeMint(to, tokenId, ""); + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { + _mint(to, tokenId); + /* require( + _checkOnERC721Received(address(0), to, tokenId, data), + "ERC721: transfer to non ERC721Receiver implementer" + ); */ + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mint(address to, uint256 tokenId) internal virtual { + tokenId = 1; + require(to != address(0), "ERC721: mint to the zero address"); + //require(!_exists(tokenId), "ERC721: token already minted"); + + _beforeTokenTransfer(address(0), to, tokenId, 1); + + // Check that tokenId was not minted by `_beforeTokenTransfer` hook + //require(!_exists(tokenId), "ERC721: token already minted"); + + unchecked { + // Will not overflow unless all 2**256 token ids are minted to the same owner. + // Given that tokens are minted one by one, it is impossible in practice that + // this ever happens. Might change if we allow batch minting. + // The ERC fails to describe this case. + _balances[to] += 1; + } + + _owners[tokenId] = to; + + emit Transfer(address(0), to, tokenId); + + _afterTokenTransfer(address(0), to, tokenId, 1); + } + + /** + * @dev Destroys `tokenId`. + * The approval is cleared when the token is burned. + * This is an internal function that does not check if the sender is authorized to operate on the token. + * + * Requirements: + * + * - `tokenId` must exist. + * + * Emits a {Transfer} event. + */ + function _burn(uint256 tokenId) internal virtual { + address owner = ERC721IncorrectMintable.ownerOf(tokenId); + + _beforeTokenTransfer(owner, address(0), tokenId, 1); + + // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook + owner = ERC721IncorrectMintable.ownerOf(tokenId); + + // Clear approvals + delete _tokenApprovals[tokenId]; + + unchecked { + // Cannot overflow, as that would require more tokens to be burned/transferred + // out than the owner initially received through minting and transferring in. + _balances[owner] -= 1; + } + delete _owners[tokenId]; + + emit Transfer(owner, address(0), tokenId); + + _afterTokenTransfer(owner, address(0), tokenId, 1); + } + + /** + * @dev Transfers `tokenId` from `from` to `to`. + * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * + * Emits a {Transfer} event. + */ + function _transfer(address from, address to, uint256 tokenId) internal virtual { + + require(ERC721IncorrectMintable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); + //require(to != address(0), "ERC721: transfer to the zero address"); + + _beforeTokenTransfer(from, to, tokenId, 1); + + // Check that tokenId was not transferred by `_beforeTokenTransfer` hook + require(ERC721IncorrectMintable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); + + // Clear approvals from the previous owner + delete _tokenApprovals[tokenId]; + uint256 balanceFrom = _balances[from] - 1; + uint256 balanceTo = _balances[to] + 1; + + _balances[from] = balanceFrom; + _balances[to] = balanceTo; + + _owners[tokenId] = to; + + emit Transfer(from, to, tokenId); + + _afterTokenTransfer(from, to, tokenId, 1); + + + } + + /** + * @dev Approve `to` to operate on `tokenId` + * + * Emits an {Approval} event. + */ + function _approve(address to, uint256 tokenId) internal virtual { + _tokenApprovals[tokenId] = to; + emit Approval(ERC721IncorrectMintable.ownerOf(tokenId), to, tokenId); + } + + /** + * @dev Approve `operator` to operate on all of `owner` tokens + * + * Emits an {ApprovalForAll} event. + */ + function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { + require(owner != operator, "ERC721: approve to caller"); + _operatorApprovals[owner][operator] = approved; + emit ApprovalForAll(owner, operator, approved); + } + + /** + * @dev Reverts if the `tokenId` has not been minted yet. + */ + function _requireMinted(uint256 tokenId) internal view virtual { + require(_exists(tokenId), "ERC721: invalid token ID"); + } + + + /** + * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is + * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. + * + * Calling conditions: + * + * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. + * - When `from` is zero, the tokens were minted for `to`. + * - When `to` is zero, ``from``'s tokens were burned. + * - `from` and `to` are never both zero. + * - `batchSize` is non-zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} + + /** + * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) { + require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); + return _ownedTokens[owner][index]; + } + + /** + * @dev See {IERC721Enumerable-totalSupply}. + */ + function totalSupply() public view virtual returns (uint256) { + return 0; + } + + /** + * @dev See {IERC721Enumerable-tokenByIndex}. + */ + function tokenByIndex(uint256 index) public view virtual returns (uint256) { + require(index < totalSupply(), "ERC721Enumerable: global index out of bounds"); + return _allTokens[index]; + } + + /** + * @dev See {ERC721-_beforeTokenTransfer}. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 firstTokenId, + uint256 batchSize + ) internal virtual { + if (batchSize > 1) { + if (from != address(0)) { + _balances[from] -= batchSize; + } + if (to != address(0)) { + _balances[to] += batchSize; + } + } + + if (batchSize > 1) { + // Will only trigger during construction. Batch transferring (minting) is not available afterwards. + revert("ERC721Enumerable: consecutive transfers not supported"); + } + + uint256 tokenId = firstTokenId; + + if (from == address(0)) { + _addTokenToAllTokensEnumeration(tokenId); + } else if (from != to) { + _removeTokenFromOwnerEnumeration(from, tokenId); + } + if (to == address(0)) { + _removeTokenFromAllTokensEnumeration(tokenId); + } else if (to != from) { + _addTokenToOwnerEnumeration(to, tokenId); + } + } + + /** + * @dev Private function to add a token to this extension's ownership-tracking data structures. + * @param to address representing the new owner of the given token ID + * @param tokenId uint256 ID of the token to be added to the tokens list of the given address + */ + function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { + uint256 length = balanceOf(to); + _ownedTokens[to][length] = tokenId; + _ownedTokensIndex[tokenId] = length; + } + + /** + * @dev Private function to add a token to this extension's token tracking data structures. + * @param tokenId uint256 ID of the token to be added to the tokens list + */ + function _addTokenToAllTokensEnumeration(uint256 tokenId) private { + _allTokensIndex[tokenId] = _allTokens.length; + _allTokens.push(tokenId); + } + + /** + * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that + * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for + * gas optimizations e.g. when performing a transfer operation (avoiding double writes). + * This has O(1) time complexity, but alters the order of the _ownedTokens array. + * @param from address representing the previous owner of the given token ID + * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address + */ + function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { + // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = balanceOf(from) - 1; + uint256 tokenIndex = _ownedTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary + if (tokenIndex != lastTokenIndex) { + uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; + + _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + } + + // This also deletes the contents at the last position of the array + delete _ownedTokensIndex[tokenId]; + delete _ownedTokens[from][lastTokenIndex]; + } + + /** + * @dev Private function to remove a token from this extension's token tracking data structures. + * This has O(1) time complexity, but alters the order of the _allTokens array. + * @param tokenId uint256 ID of the token to be removed from the tokens list + */ + function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { + // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and + // then delete the last slot (swap and pop). + + uint256 lastTokenIndex = _allTokens.length - 1; + uint256 tokenIndex = _allTokensIndex[tokenId]; + + // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so + // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding + // an 'if' statement (like in _removeTokenFromOwnerEnumeration) + uint256 lastTokenId = _allTokens[lastTokenIndex]; + + _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token + _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index + + // This also deletes the contents at the last position of the array + delete _allTokensIndex[tokenId]; + _allTokens.pop(); + } +} diff --git a/contracts/ERC721/internal/echidna.config.yaml b/contracts/ERC721/internal/echidna.config.yaml deleted file mode 100644 index b5ab450..0000000 --- a/contracts/ERC721/internal/echidna.config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -coverage: true -corpusDir: "corpus" -testMode: assertion -testLimit: 100000 -deployer: "0x10000" -sender: ["0x10000", "0x20000", "0x30000"] \ No newline at end of file diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol index 398360e..710ad59 100644 --- a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -1,6 +1,7 @@ pragma solidity ^0.8.13; import "../util/ERC721TestBase.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; abstract contract CryticERC721BasicProperties is CryticERC721TestBase { using Address for address; diff --git a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol index d2d09d7..020f65c 100644 --- a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol @@ -26,14 +26,25 @@ abstract contract CryticERC721BurnableProperties is CryticERC721TestBase, ERC721 } // A burned token should not be transferrable - function test_ERC721_burnRevertOnTransfer(address target) public virtual { + function test_ERC721_burnRevertOnTransferFromPreviousOwner(address target) public virtual { require(isMintableOrBurnable); uint256 selfBalance = balanceOf(msg.sender); require(selfBalance > 0); uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); burn(tokenId); - safeTransferFrom(msg.sender, target, tokenId); + transferFrom(msg.sender, target, tokenId); + assertWithMsg(false, "Transferring a burned token didn't revert"); + } + + function test_ERC721_burnRevertOnTransferFromZeroAddress(address target) public virtual { + require(isMintableOrBurnable); + uint256 selfBalance = balanceOf(msg.sender); + require(selfBalance > 0); + + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); + burn(tokenId); + transferFrom(address(0), target, tokenId); assertWithMsg(false, "Transferring a burned token didn't revert"); } diff --git a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol index 7757092..89d6967 100644 --- a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.13; import "../util/ERC721TestBase.sol"; abstract contract CryticERC721MintableProperties is CryticERC721TestBase { - using Address for address; + //////////////////////////////////////// // Properties @@ -25,11 +25,12 @@ abstract contract CryticERC721MintableProperties is CryticERC721TestBase { uint256 endIndex = selfBalance + amount; _customMint(amount); + assertEq(selfBalance + amount, balanceOf(msg.sender), "Receiver supply was not correctly increased"); + for(uint256 i = selfBalance; i < endIndex; i++) { uint256 tokenId = tokenOfOwnerByIndex(msg.sender, i); assertWithMsg(ownerOf(tokenId) == msg.sender, "Token ID was not minted to receiver"); } - assertEq(selfBalance + amount, balanceOf(msg.sender), "Receiver supply was not correctly increased"); } // the total supply should never be larger than the max supply diff --git a/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol b/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol similarity index 67% rename from contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol rename to contracts/ERC721/internal/test/standard/ERC721BasicTests.sol index 29210c6..e10a39e 100644 --- a/contracts/ERC721/external/test/standard/ERC721ShouldRevert.sol +++ b/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol @@ -2,20 +2,27 @@ pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import {CryticERC721ExternalPropertyTests} from "../../ERC721ExternalPropertyTests.sol"; -import {IERC721Internal} from "../../../util/IERC721Internal.sol"; +import {CryticERC721BasicProperties} from "../../properties/ERC721BasicProperties.sol"; import {MockReceiver} from "../../util/MockReceiver.sol"; -contract ERC721ShouldRevert is ERC721, ERC721Enumerable { +contract ERC721BasicTestsInternal is CryticERC721BasicProperties { using Address for address; uint256 public counter; - uint256 public maxSupply; - bool public isMintableOrBurnable; - constructor() ERC721("OZERC721","OZ") { + constructor() ERC721("ERC721BasicTestsInternal","ERC721BasicTestsInternal") { maxSupply = 100; isMintableOrBurnable = true; + hasMaxSupply = false; + safeReceiver = new MockReceiver(true); + unsafeReceiver = new MockReceiver(false); + } + + function mint(uint256 amount) public { + //require(totalSupply() + amount <= maxSupply); + for (uint256 i; i < amount; i++) { + _mint(msg.sender, counter++); + } } function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { @@ -42,12 +49,8 @@ contract ERC721ShouldRevert is ERC721, ERC721Enumerable { //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); if (from == address(0)) { _mint(to, tokenId); - } else if (getApproved(tokenId) != msg.sender && !isApprovedForAll(from, msg.sender) || to == address(0)) { - _burn(tokenId); - _mint(to, tokenId); - } else { - ERC721._transfer(from, to, tokenId); } + _approve(address(this), tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { @@ -72,40 +75,30 @@ contract ERC721ShouldRevert is ERC721, ERC721Enumerable { function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal virtual - override(ERC721, ERC721Enumerable) + override { - ERC721Enumerable._beforeTokenTransfer(from, to, tokenId, batchSize); + super._beforeTokenTransfer(from, to, tokenId, batchSize); } function supportsInterface(bytes4 interfaceId) public view virtual - override(ERC721, ERC721Enumerable) + override returns (bool) { - return ERC721Enumerable.supportsInterface(interfaceId); + return super.supportsInterface(interfaceId); } - function _customMint(address to, uint256 amount) public virtual { - maxSupply += amount; - - for (uint256 i; i < amount; i++) { - _mint(to, counter++); - } + function _customMint(uint256 amount) internal virtual { + mint(amount); } - function _customMaxSupply() public virtual view returns (uint256) { + function _customMaxSupply() internal virtual view returns (uint256) { return maxSupply; } } -contract TestHarness is CryticERC721ExternalPropertyTests { - - constructor() { - token = IERC721Internal(address(new ERC721ShouldRevert())); - mockSafeReceiver = new MockReceiver(true); - mockUnsafeReceiver = new MockReceiver(false); - } - +contract TestHarness is ERC721BasicTestsInternal { + constructor() {} } \ No newline at end of file diff --git a/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol b/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol new file mode 100644 index 0000000..db958df --- /dev/null +++ b/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol @@ -0,0 +1,96 @@ +pragma solidity ^0.8.13; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import {CryticERC721BurnableProperties} from "../../properties/ERC721BurnableProperties.sol"; +import {MockReceiver} from "../../util/MockReceiver.sol"; + +contract ERC721BurnableTestsInternal is CryticERC721BurnableProperties { + using Address for address; + + uint256 public counter; + + constructor() ERC721("ERC721BasicTestsInternal","ERC721BasicTestsInternal") { + maxSupply = 100; + isMintableOrBurnable = true; + hasMaxSupply = false; + safeReceiver = new MockReceiver(true); + unsafeReceiver = new MockReceiver(false); + } + + function burn(uint256 amount) public virtual override { + //require(totalSupply() + amount <= maxSupply); + for (uint256 i; i < amount; i++) { + _mint(msg.sender, counter++); + } + } + + function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { + //require(owner != address(0), "ERC721: address zero is not a valid owner"); + return owner == address(0) ? 0 : super.balanceOf(owner); + } + + function ownerOf(uint256 tokenId) public view virtual override(ERC721, IERC721) returns (address) { + address owner = _ownerOf(tokenId); + //require(owner != address(0), "ERC721: invalid token ID"); + return owner; + } + + function approve(address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + if(_exists(tokenId)) { + super.approve(to, tokenId); + } + + // Does not revert if token doesn't exist + } + + function transferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + //solhint-disable-next-line max-line-length + //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); + if (from == address(0)) { + _mint(to, tokenId); + } + _approve(address(this), tokenId); + } + + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { + if (to.isContract()) { + try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, "") returns (bytes4 retval) { + if (retval != IERC721Receiver.onERC721Received.selector) { + _transfer(from, to, tokenId); + } else { + safeTransferFrom(from, to, tokenId, ""); + } + + } catch (bytes memory reason) { + _transfer(from, to, tokenId); + } + } else { + safeTransferFrom(from, to, tokenId, ""); + } + + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} + +contract TestHarness is ERC721BurnableTestsInternal { + constructor() {} +} \ No newline at end of file diff --git a/contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol b/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol similarity index 81% rename from contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol rename to contracts/ERC721/internal/test/standard/ERC721MintableTests.sol index 81cd25c..5d8649a 100644 --- a/contracts/ERC721/internal/test/standard/ERC721ShouldRevert.sol +++ b/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol @@ -2,16 +2,15 @@ pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import {CryticERC721InternalPropertyTests} from "../../ERC721InternalPropertyTests.sol"; +import {CryticERC721MintableProperties} from "../../properties/ERC721MintableProperties.sol"; import {MockReceiver} from "../../util/MockReceiver.sol"; -contract ERC721ShouldRevertInternal is CryticERC721InternalPropertyTests { +contract ERC721MintableTestsInternal is CryticERC721MintableProperties { using Address for address; uint256 public counter; - uint256 public maxSupply; - constructor() ERC721("ERC721ShouldRevert","ERC721ShouldRevert") { + constructor() ERC721("ERC721BasicTestsInternal","ERC721BasicTestsInternal") { maxSupply = 100; isMintableOrBurnable = true; hasMaxSupply = false; @@ -21,9 +20,9 @@ contract ERC721ShouldRevertInternal is CryticERC721InternalPropertyTests { function mint(uint256 amount) public { //require(totalSupply() + amount <= maxSupply); - for (uint256 i; i < amount; i++) { + /* for (uint256 i; i < amount; i++) { _mint(msg.sender, counter++); - } + } */ } function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { @@ -50,12 +49,8 @@ contract ERC721ShouldRevertInternal is CryticERC721InternalPropertyTests { //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); if (from == address(0)) { _mint(to, tokenId); - } else if (getApproved(tokenId) != msg.sender && !isApprovedForAll(from, msg.sender) || to == address(0)) { - _burn(tokenId); - _mint(to, tokenId); - } else { - ERC721._transfer(from, to, tokenId); } + _approve(address(this), tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { @@ -80,7 +75,7 @@ contract ERC721ShouldRevertInternal is CryticERC721InternalPropertyTests { function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal virtual - override(CryticERC721InternalPropertyTests) + override { super._beforeTokenTransfer(from, to, tokenId, batchSize); } @@ -89,7 +84,7 @@ contract ERC721ShouldRevertInternal is CryticERC721InternalPropertyTests { public view virtual - override(CryticERC721InternalPropertyTests) + override returns (bool) { return super.supportsInterface(interfaceId); @@ -104,6 +99,6 @@ contract ERC721ShouldRevertInternal is CryticERC721InternalPropertyTests { } } -contract TestHarness is ERC721ShouldRevertInternal { +contract TestHarness is ERC721MintableTestsInternal { constructor() {} } \ No newline at end of file diff --git a/contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol b/contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol deleted file mode 100644 index 3f255cf..0000000 --- a/contracts/ERC721/internal/test/standard/ERC721NonCompliant.sol +++ /dev/null @@ -1,55 +0,0 @@ -pragma solidity ^0.8.13; - -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import "../../ERC721InternalPropertyTests.sol"; - -contract ERC721NonCompliant is ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests { - - uint256 public counter; - uint256 public maxSupply; - - constructor() ERC721("OZERC721","OZ") { - maxSupply = 100; - } - - function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { - //require(owner != address(0), "ERC721: address zero is not a valid owner"); - return owner == address(0) ? 0 : super.balanceOf(owner); - } - - function ownerOf(uint256 tokenId) public view virtual override(ERC721, IERC721) returns (address) { - address owner = _ownerOf(tokenId); - //require(owner != address(0), "ERC721: invalid token ID"); - return owner; - } - - // The following functions are overrides required by Solidity. - function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) - internal - virtual - override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) - { - super._beforeTokenTransfer(from, to, tokenId, batchSize); - } - - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC721, ERC721Enumerable, CryticERC721InternalPropertyTests) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function _customMint(uint256 amount) internal virtual override { - for (uint256 i; i < amount; i++) { - _mint(msg.sender, counter++); - } - } - - function _customMaxSupply() internal virtual override view returns (uint256) { - return maxSupply; - } -} \ No newline at end of file diff --git a/contracts/ERC721/internal/util/ERC721TestBase.sol b/contracts/ERC721/internal/util/ERC721TestBase.sol index 7d15257..c1093c4 100644 --- a/contracts/ERC721/internal/util/ERC721TestBase.sol +++ b/contracts/ERC721/internal/util/ERC721TestBase.sol @@ -11,6 +11,7 @@ abstract contract CryticERC721TestBase is ERC721, ERC721Enumerable, PropertiesAs // Is the contract allowed to change its total supply? bool isMintableOrBurnable; bool hasMaxSupply; + uint256 maxSupply; MockReceiver safeReceiver; MockReceiver unsafeReceiver; From 41195371ea48a68451efd1ec127c5cd6240e7d85 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Fri, 31 Mar 2023 17:33:37 +0200 Subject: [PATCH 08/23] added erc721 tests folder --- tests/ERC721/foundry/src/ExampleToken.sol | 2 +- tests/ERC721/foundry/test/CryticTest.sol | 6 - tests/ERC721/foundry/test/CryticTestExt.sol | 13 - tests/ERC721/hardhat/contracts/CryticTest.sol | 9 + .../hardhat/contracts/CryticTestExt.sol | 27 + .../ERC721/hardhat/contracts/ExampleToken.sol | 41 + tests/ERC721/hardhat/hardhat.config.js | 3 + tests/ERC721/hardhat/package-lock.json | 6853 +++++++++++++++++ tests/ERC721/hardhat/package.json | 9 + .../hardhat/tests/echidna-config-ext.yaml | 7 + .../ERC721/hardhat/tests/echidna-config.yaml | 5 + tests/ERC721/hardhat/yarn.lock | 2158 ++++++ 12 files changed, 9113 insertions(+), 20 deletions(-) create mode 100644 tests/ERC721/hardhat/contracts/CryticTest.sol create mode 100644 tests/ERC721/hardhat/contracts/CryticTestExt.sol create mode 100644 tests/ERC721/hardhat/contracts/ExampleToken.sol create mode 100644 tests/ERC721/hardhat/hardhat.config.js create mode 100644 tests/ERC721/hardhat/package-lock.json create mode 100644 tests/ERC721/hardhat/package.json create mode 100644 tests/ERC721/hardhat/tests/echidna-config-ext.yaml create mode 100644 tests/ERC721/hardhat/tests/echidna-config.yaml create mode 100644 tests/ERC721/hardhat/yarn.lock diff --git a/tests/ERC721/foundry/src/ExampleToken.sol b/tests/ERC721/foundry/src/ExampleToken.sol index 01a12c7..700bbe5 100644 --- a/tests/ERC721/foundry/src/ExampleToken.sol +++ b/tests/ERC721/foundry/src/ExampleToken.sol @@ -17,7 +17,7 @@ contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable, Pausable, Own _unpause(); } - function mint(address to, uint256 tokenId) public virtual onlyOwner { + function mint(address to, uint256 tokenId) public virtual { _mint(to, tokenId); } diff --git a/tests/ERC721/foundry/test/CryticTest.sol b/tests/ERC721/foundry/test/CryticTest.sol index b2f99be..7916d56 100644 --- a/tests/ERC721/foundry/test/CryticTest.sol +++ b/tests/ERC721/foundry/test/CryticTest.sol @@ -4,12 +4,6 @@ import "../src/ExampleToken.sol"; contract CryticERC721InternalHarness is ExampleToken, CryticERC721BasicProperties { constructor() { - // Setup balances for USER1, USER2 and USER3: - _mint(USER1, INITIAL_BALANCE); - _mint(USER2, INITIAL_BALANCE); - _mint(USER3, INITIAL_BALANCE); - // Setup total supply: - initialSupply = totalSupply(); isMintableOrBurnable = true; } } diff --git a/tests/ERC721/foundry/test/CryticTestExt.sol b/tests/ERC721/foundry/test/CryticTestExt.sol index ed9b2a8..0718610 100644 --- a/tests/ERC721/foundry/test/CryticTestExt.sol +++ b/tests/ERC721/foundry/test/CryticTestExt.sol @@ -19,21 +19,8 @@ contract ERC721Mock is ExampleToken { address constant USER2 = address(0x20000); address constant USER3 = address(0x30000); - // Initial balance for users' accounts - uint256 constant INITIAL_BALANCE = 5; - bool public isMintableOrBurnable; - uint256 public initialSupply; constructor () { - for(uint256 i; i < INITIAL_BALANCE; i=i + 4) { - _mint(USER1, i); - _mint(USER2, i+1); - _mint(USER3, i+2); - _mint(msg.sender, i+3); - } - - - initialSupply = totalSupply(); isMintableOrBurnable = true; } diff --git a/tests/ERC721/hardhat/contracts/CryticTest.sol b/tests/ERC721/hardhat/contracts/CryticTest.sol new file mode 100644 index 0000000..f7ab13e --- /dev/null +++ b/tests/ERC721/hardhat/contracts/CryticTest.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.8.0; +import "@crytic/properties/ERC721/internal/properties/ERC721BasicProperties.sol"; +import "../src/ExampleToken.sol"; + +contract CryticERC721InternalHarness is ExampleToken, CryticERC721BasicProperties { + constructor() { + isMintableOrBurnable = true; + } +} diff --git a/tests/ERC721/hardhat/contracts/CryticTestExt.sol b/tests/ERC721/hardhat/contracts/CryticTestExt.sol new file mode 100644 index 0000000..0979389 --- /dev/null +++ b/tests/ERC721/hardhat/contracts/CryticTestExt.sol @@ -0,0 +1,27 @@ +pragma solidity ^0.8.0; +import "../src/ExampleToken.sol"; +import {IERC721Mock} from "@crytic/properties/ERC721/external/util/IERC721Mock.sol"; +import {CryticERC721ExternalBasicProperties} from "@crytic/properties/ERC721/external/properties/ERC721xternalBasicProperties.sol"; + +contract CryticERC721ExternalHarness is CryticERC721ExternalBasicProperties { + + constructor() { + // Deploy ERC721 + token = IERC721Mock(address(new ERC721Mock())); + } + +} + +contract ERC721Mock is ExampleToken { + + // Address originating transactions in Echidna (must be equal to the `sender` configuration parameter) + address constant USER1 = address(0x10000); + address constant USER2 = address(0x20000); + address constant USER3 = address(0x30000); + + bool public isMintableOrBurnable; + constructor () { + isMintableOrBurnable = true; + } + +} diff --git a/tests/ERC721/hardhat/contracts/ExampleToken.sol b/tests/ERC721/hardhat/contracts/ExampleToken.sol new file mode 100644 index 0000000..700bbe5 --- /dev/null +++ b/tests/ERC721/hardhat/contracts/ExampleToken.sol @@ -0,0 +1,41 @@ +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import "@openzeppelin/contracts/security/Pausable.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable, Pausable, Ownable { + constructor() ERC721("Example token", "EXT") {} + + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + + function mint(address to, uint256 tokenId) public virtual { + _mint(to, tokenId); + } + + // Overrides + + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + override(ERC721, ERC721Enumerable) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC721, ERC721Enumerable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} diff --git a/tests/ERC721/hardhat/hardhat.config.js b/tests/ERC721/hardhat/hardhat.config.js new file mode 100644 index 0000000..9b0caf6 --- /dev/null +++ b/tests/ERC721/hardhat/hardhat.config.js @@ -0,0 +1,3 @@ +module.exports = { + solidity: "0.8.13", +}; diff --git a/tests/ERC721/hardhat/package-lock.json b/tests/ERC721/hardhat/package-lock.json new file mode 100644 index 0000000..9c2cfac --- /dev/null +++ b/tests/ERC721/hardhat/package-lock.json @@ -0,0 +1,6853 @@ +{ + "name": "hardhat", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "@crytic/properties": "file:../../..", + "@openzeppelin/contracts": "^4.8.0" + }, + "devDependencies": { + "hardhat": "^2.12.4" + } + }, + "../../..": { + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@openzeppelin/contracts": "^4.7.3", + "solmate": "^6.6.1" + }, + "devDependencies": { + "hardhat": "^2.9.3" + } + }, + "node_modules/@crytic/properties": { + "resolved": "../../..", + "link": true + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dev": true, + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nomicfoundation/ethereumjs-block": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", + "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-block/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", + "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-ethash": "^2.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "abstract-level": "^1.0.3", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "level": "^8.0.0", + "lru-cache": "^5.1.1", + "memory-level": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-blockchain/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", + "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "crc-32": "^1.2.0" + } + }, + "node_modules/@nomicfoundation/ethereumjs-ethash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", + "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "abstract-level": "^1.0.3", + "bigint-crypto-utils": "^3.0.23", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-ethash/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", + "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-evm/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", + "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", + "dev": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", + "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1" + } + }, + "node_modules/@nomicfoundation/ethereumjs-statemanager/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-trie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", + "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-trie/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", + "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", + "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", + "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", + "dev": true, + "dependencies": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nomicfoundation/ethereumjs-vm/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", + "dev": true, + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", + "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", + "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", + "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", + "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", + "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", + "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", + "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", + "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", + "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", + "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.0.tgz", + "integrity": "sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==" + }, + "node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dev": true, + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/async-eventemitter": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", + "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", + "dev": true + }, + "node_modules/@types/bn.js": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", + "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==", + "dev": true + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-level": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", + "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true, + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "dev": true, + "dependencies": { + "async": "^2.4.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bigint-crypto-utils": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz", + "integrity": "sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==", + "dev": true, + "dependencies": { + "bigint-mod-arith": "^3.1.0" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/bigint-mod-arith": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz", + "integrity": "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==", + "dev": true, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browser-level": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", + "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "dev": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/classic-level": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", + "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dev": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/hardhat": { + "version": "2.12.4", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.4.tgz", + "integrity": "sha512-rc9S2U/4M+77LxW1Kg7oqMMmjl81tzn5rNFARhbXKUA1am/nhfMJEujOjuKvt+ZGMiZ11PYSe8gyIpB/aRNDgw==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@nomicfoundation/ethereumjs-vm": "^6.0.0", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "abort-controller": "^3.0.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "qs": "^6.7.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.4.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/cli.js" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || ^18.0.0" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "dev": true + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dev": true, + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "dev": true, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", + "dev": true, + "dependencies": { + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/mcl-wasm": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", + "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", + "dev": true, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/memory-level": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", + "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", + "dev": true, + "dependencies": { + "abstract-level": "^1.0.0", + "functional-red-black-tree": "^1.0.1", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dev": true, + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "dev": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node_modules/node-gyp-build": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", + "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "dev": true, + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dev": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "dev": true + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.14.0.tgz", + "integrity": "sha512-yJlHYw6yXPPsuOH0x2Ib1Km61vu4hLiRRQoafs+WUgX1vO64vgnxiCEN9dpIrhZyHFsai3F0AEj4P9zy19enEQ==", + "dev": true, + "dependencies": { + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=12.18" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@crytic/properties": { + "version": "file:../../..", + "requires": { + "@openzeppelin/contracts": "^4.7.3", + "hardhat": "^2.9.3", + "solmate": "^6.6.1" + } + }, + "@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "dev": true, + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "dev": true, + "requires": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "dev": true, + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "dev": true + }, + "@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "dev": true, + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "dev": true, + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "dev": true, + "requires": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "dev": true, + "requires": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dev": true, + "requires": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + } + }, + "@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true + }, + "@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true + }, + "@nomicfoundation/ethereumjs-block": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", + "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-blockchain": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", + "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-ethash": "^2.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "abstract-level": "^1.0.3", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "level": "^8.0.0", + "lru-cache": "^5.1.1", + "memory-level": "^1.0.0" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-common": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", + "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "crc-32": "^1.2.0" + } + }, + "@nomicfoundation/ethereumjs-ethash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", + "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "abstract-level": "^1.0.3", + "bigint-crypto-utils": "^3.0.23", + "ethereum-cryptography": "0.1.3" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-evm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", + "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-rlp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", + "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", + "dev": true + }, + "@nomicfoundation/ethereumjs-statemanager": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", + "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-trie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", + "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-tx": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", + "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "ethereum-cryptography": "0.1.3" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-util": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", + "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", + "ethereum-cryptography": "0.1.3" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/ethereumjs-vm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", + "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", + "dev": true, + "requires": { + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@types/async-eventemitter": "^0.2.1", + "async-eventemitter": "^0.2.4", + "debug": "^4.3.3", + "ethereum-cryptography": "0.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "rustbn.js": "~0.2.0" + }, + "dependencies": { + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "@nomicfoundation/solidity-analyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz", + "integrity": "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==", + "dev": true, + "requires": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.0", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.0", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.1.0", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.0" + } + }, + "@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz", + "integrity": "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz", + "integrity": "sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-freebsd-x64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz", + "integrity": "sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz", + "integrity": "sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz", + "integrity": "sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz", + "integrity": "sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz", + "integrity": "sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz", + "integrity": "sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz", + "integrity": "sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw==", + "dev": true, + "optional": true + }, + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz", + "integrity": "sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA==", + "dev": true, + "optional": true + }, + "@openzeppelin/contracts": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.0.tgz", + "integrity": "sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==" + }, + "@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dev": true + }, + "@scure/bip32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, + "@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dev": true, + "requires": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dev": true, + "requires": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + } + }, + "@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dev": true, + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true + }, + "@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dev": true, + "requires": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@types/async-eventemitter": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", + "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", + "dev": true + }, + "@types/bn.js": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "dev": true + }, + "@types/node": { + "version": "18.11.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", + "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==", + "dev": true + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "abstract-level": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", + "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", + "dev": true, + "requires": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + } + }, + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "dev": true, + "requires": { + "async": "^2.4.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bigint-crypto-utils": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz", + "integrity": "sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==", + "dev": true, + "requires": { + "bigint-mod-arith": "^3.1.0" + } + }, + "bigint-mod-arith": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz", + "integrity": "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "browser-level": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", + "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "dev": true, + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "requires": { + "streamsearch": "^1.1.0" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "classic-level": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", + "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", + "dev": true, + "requires": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true + }, + "crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "dev": true, + "requires": { + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" + } + }, + "ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "dev": true, + "requires": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + } + } + }, + "ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + } + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true + }, + "fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "hardhat": { + "version": "2.12.4", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.12.4.tgz", + "integrity": "sha512-rc9S2U/4M+77LxW1Kg7oqMMmjl81tzn5rNFARhbXKUA1am/nhfMJEujOjuKvt+ZGMiZ11PYSe8gyIpB/aRNDgw==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/ethereumjs-block": "^4.0.0", + "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", + "@nomicfoundation/ethereumjs-common": "^3.0.0", + "@nomicfoundation/ethereumjs-evm": "^1.0.0", + "@nomicfoundation/ethereumjs-rlp": "^4.0.0", + "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", + "@nomicfoundation/ethereumjs-trie": "^5.0.0", + "@nomicfoundation/ethereumjs-tx": "^4.0.0", + "@nomicfoundation/ethereumjs-util": "^8.0.0", + "@nomicfoundation/ethereumjs-vm": "^6.0.0", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "abort-controller": "^3.0.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "qs": "^6.7.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.4.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dev": true, + "requires": { + "fp-ts": "^1.0.0" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "dev": true, + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", + "dev": true, + "requires": { + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" + } + }, + "level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "dev": true + }, + "level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dev": true, + "requires": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "mcl-wasm": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", + "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memory-level": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", + "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", + "dev": true, + "requires": { + "abstract-level": "^1.0.0", + "functional-red-black-tree": "^1.0.1", + "module-error": "^1.0.1" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dev": true, + "requires": { + "obliterator": "^2.0.0" + } + }, + "mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "dev": true, + "requires": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true + }, + "napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node-gyp-build": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", + "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "requires": { + "bn.js": "^5.2.0" + } + }, + "run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "dev": true, + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dev": true, + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true + } + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "dev": true + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true + }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "undici": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.14.0.tgz", + "integrity": "sha512-yJlHYw6yXPPsuOH0x2Ib1Km61vu4hLiRRQoafs+WUgX1vO64vgnxiCEN9dpIrhZyHFsai3F0AEj4P9zy19enEQ==", + "dev": true, + "requires": { + "busboy": "^1.6.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "requires": {} + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/tests/ERC721/hardhat/package.json b/tests/ERC721/hardhat/package.json new file mode 100644 index 0000000..f7208ab --- /dev/null +++ b/tests/ERC721/hardhat/package.json @@ -0,0 +1,9 @@ +{ + "devDependencies": { + "hardhat": "^2.12.4" + }, + "dependencies": { + "@openzeppelin/contracts": "^4.8.0", + "@crytic/properties": "file:../../.." + } +} diff --git a/tests/ERC721/hardhat/tests/echidna-config-ext.yaml b/tests/ERC721/hardhat/tests/echidna-config-ext.yaml new file mode 100644 index 0000000..6a65522 --- /dev/null +++ b/tests/ERC721/hardhat/tests/echidna-config-ext.yaml @@ -0,0 +1,7 @@ +corpusDir: "tests/echidna-corpus-ext" +testMode: assertion +testLimit: 10000 +deployer: "0x10000" +sender: ["0x10000", "0x20000", "0x30000"] +multi-abi: true + diff --git a/tests/ERC721/hardhat/tests/echidna-config.yaml b/tests/ERC721/hardhat/tests/echidna-config.yaml new file mode 100644 index 0000000..c5191d2 --- /dev/null +++ b/tests/ERC721/hardhat/tests/echidna-config.yaml @@ -0,0 +1,5 @@ +corpusDir: "tests/echidna-corpus" +testMode: assertion +testLimit: 10000 +deployer: "0x10000" +sender: ["0x10000", "0x20000", "0x30000"] diff --git a/tests/ERC721/hardhat/yarn.lock b/tests/ERC721/hardhat/yarn.lock new file mode 100644 index 0000000..0018d21 --- /dev/null +++ b/tests/ERC721/hardhat/yarn.lock @@ -0,0 +1,2158 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@crytic/properties@file:../../..": + "resolved" "file:../../.." + "version" "0.0.1" + dependencies: + "@openzeppelin/contracts" "^4.7.3" + "solmate" "^6.6.1" + +"@ethersproject/abi@^5.1.2": + "integrity" "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==" + "resolved" "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/abstract-provider@^5.7.0": + "integrity" "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==" + "resolved" "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + +"@ethersproject/abstract-signer@^5.7.0": + "integrity" "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==" + "resolved" "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/address@^5.7.0": + "integrity" "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==" + "resolved" "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + +"@ethersproject/base64@^5.7.0": + "integrity" "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==" + "resolved" "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bytes" "^5.7.0" + +"@ethersproject/bignumber@^5.7.0": + "integrity" "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==" + "resolved" "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "bn.js" "^5.2.1" + +"@ethersproject/bytes@^5.7.0": + "integrity" "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==" + "resolved" "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/constants@^5.7.0": + "integrity" "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==" + "resolved" "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bignumber" "^5.7.0" + +"@ethersproject/hash@^5.7.0": + "integrity" "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==" + "resolved" "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/keccak256@^5.7.0": + "integrity" "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==" + "resolved" "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bytes" "^5.7.0" + "js-sha3" "0.8.0" + +"@ethersproject/logger@^5.7.0": + "integrity" "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==" + "resolved" "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz" + "version" "5.7.0" + +"@ethersproject/networks@^5.7.0": + "integrity" "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==" + "resolved" "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz" + "version" "5.7.1" + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/properties@^5.7.0": + "integrity" "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==" + "resolved" "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@^5.7.0": + "integrity" "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==" + "resolved" "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/signing-key@^5.7.0": + "integrity" "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==" + "resolved" "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "bn.js" "^5.2.1" + "elliptic" "6.5.4" + "hash.js" "1.1.7" + +"@ethersproject/strings@^5.7.0": + "integrity" "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==" + "resolved" "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/transactions@^5.7.0": + "integrity" "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==" + "resolved" "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz" + "version" "5.7.0" + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + +"@ethersproject/web@^5.7.0": + "integrity" "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==" + "resolved" "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz" + "version" "5.7.1" + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@metamask/eth-sig-util@^4.0.0": + "integrity" "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==" + "resolved" "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "ethereumjs-abi" "^0.6.8" + "ethereumjs-util" "^6.2.1" + "ethjs-util" "^0.1.6" + "tweetnacl" "^1.0.3" + "tweetnacl-util" "^0.15.1" + +"@noble/hashes@~1.1.1", "@noble/hashes@1.1.2": + "integrity" "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==" + "resolved" "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz" + "version" "1.1.2" + +"@noble/secp256k1@~1.6.0", "@noble/secp256k1@1.6.3": + "integrity" "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==" + "resolved" "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz" + "version" "1.6.3" + +"@nomicfoundation/ethereumjs-block@^4.0.0": + "integrity" "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "ethereum-cryptography" "0.1.3" + +"@nomicfoundation/ethereumjs-blockchain@^6.0.0": + "integrity" "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-ethash" "^2.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "abstract-level" "^1.0.3" + "debug" "^4.3.3" + "ethereum-cryptography" "0.1.3" + "level" "^8.0.0" + "lru-cache" "^5.1.1" + "memory-level" "^1.0.0" + +"@nomicfoundation/ethereumjs-common@^3.0.0": + "integrity" "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "crc-32" "^1.2.0" + +"@nomicfoundation/ethereumjs-ethash@^2.0.0": + "integrity" "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "abstract-level" "^1.0.3" + "bigint-crypto-utils" "^3.0.23" + "ethereum-cryptography" "0.1.3" + +"@nomicfoundation/ethereumjs-evm@^1.0.0": + "integrity" "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@types/async-eventemitter" "^0.2.1" + "async-eventemitter" "^0.2.4" + "debug" "^4.3.3" + "ethereum-cryptography" "0.1.3" + "mcl-wasm" "^0.7.1" + "rustbn.js" "~0.2.0" + +"@nomicfoundation/ethereumjs-rlp@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2": + "integrity" "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz" + "version" "4.0.0" + +"@nomicfoundation/ethereumjs-statemanager@^1.0.0": + "integrity" "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "debug" "^4.3.3" + "ethereum-cryptography" "0.1.3" + "functional-red-black-tree" "^1.0.1" + +"@nomicfoundation/ethereumjs-trie@^5.0.0": + "integrity" "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "ethereum-cryptography" "0.1.3" + "readable-stream" "^3.6.0" + +"@nomicfoundation/ethereumjs-tx@^4.0.0": + "integrity" "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "ethereum-cryptography" "0.1.3" + +"@nomicfoundation/ethereumjs-util@^8.0.0": + "integrity" "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz" + "version" "8.0.0" + dependencies: + "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2" + "ethereum-cryptography" "0.1.3" + +"@nomicfoundation/ethereumjs-vm@^6.0.0": + "integrity" "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-blockchain" "^6.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-evm" "^1.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-statemanager" "^1.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@types/async-eventemitter" "^0.2.1" + "async-eventemitter" "^0.2.4" + "debug" "^4.3.3" + "ethereum-cryptography" "0.1.3" + "functional-red-black-tree" "^1.0.1" + "mcl-wasm" "^0.7.1" + "rustbn.js" "~0.2.0" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": + "integrity" "sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz" + "version" "0.1.0" + +"@nomicfoundation/solidity-analyzer@^0.1.0": + "integrity" "sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg==" + "resolved" "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz" + "version" "0.1.0" + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.0" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.0" + "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.0" + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.0" + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.0" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.0" + +"@openzeppelin/contracts@^4.8.0": + "integrity" "sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw==" + "resolved" "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.0.tgz" + "version" "4.8.0" + +"@scure/base@~1.1.0": + "integrity" "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==" + "resolved" "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz" + "version" "1.1.1" + +"@scure/bip32@1.1.0": + "integrity" "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==" + "resolved" "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "@noble/hashes" "~1.1.1" + "@noble/secp256k1" "~1.6.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.1.0": + "integrity" "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==" + "resolved" "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "@noble/hashes" "~1.1.1" + "@scure/base" "~1.1.0" + +"@sentry/core@5.30.0": + "integrity" "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==" + "resolved" "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz" + "version" "5.30.0" + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + "tslib" "^1.9.3" + +"@sentry/hub@5.30.0": + "integrity" "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==" + "resolved" "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz" + "version" "5.30.0" + dependencies: + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + "tslib" "^1.9.3" + +"@sentry/minimal@5.30.0": + "integrity" "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==" + "resolved" "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz" + "version" "5.30.0" + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/types" "5.30.0" + "tslib" "^1.9.3" + +"@sentry/node@^5.18.1": + "integrity" "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==" + "resolved" "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz" + "version" "5.30.0" + dependencies: + "@sentry/core" "5.30.0" + "@sentry/hub" "5.30.0" + "@sentry/tracing" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + "cookie" "^0.4.1" + "https-proxy-agent" "^5.0.0" + "lru_map" "^0.3.3" + "tslib" "^1.9.3" + +"@sentry/tracing@5.30.0": + "integrity" "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==" + "resolved" "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz" + "version" "5.30.0" + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + "tslib" "^1.9.3" + +"@sentry/types@5.30.0": + "integrity" "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==" + "resolved" "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz" + "version" "5.30.0" + +"@sentry/utils@5.30.0": + "integrity" "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==" + "resolved" "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz" + "version" "5.30.0" + dependencies: + "@sentry/types" "5.30.0" + "tslib" "^1.9.3" + +"@types/async-eventemitter@^0.2.1": + "integrity" "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==" + "resolved" "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz" + "version" "0.2.1" + +"@types/bn.js@^4.11.3": + "integrity" "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==" + "resolved" "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz" + "version" "4.11.6" + dependencies: + "@types/node" "*" + +"@types/bn.js@^5.1.0": + "integrity" "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==" + "resolved" "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz" + "version" "5.1.1" + dependencies: + "@types/node" "*" + +"@types/lru-cache@^5.1.0": + "integrity" "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" + "resolved" "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz" + "version" "5.1.1" + +"@types/node@*": + "integrity" "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==" + "resolved" "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz" + "version" "18.11.15" + +"@types/pbkdf2@^3.0.0": + "integrity" "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==" + "resolved" "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "@types/node" "*" + +"@types/secp256k1@^4.0.1": + "integrity" "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==" + "resolved" "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "@types/node" "*" + +"abort-controller@^3.0.0": + "integrity" "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==" + "resolved" "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "event-target-shim" "^5.0.0" + +"abstract-level@^1.0.0", "abstract-level@^1.0.2", "abstract-level@^1.0.3": + "integrity" "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==" + "resolved" "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz" + "version" "1.0.3" + dependencies: + "buffer" "^6.0.3" + "catering" "^2.1.0" + "is-buffer" "^2.0.5" + "level-supports" "^4.0.0" + "level-transcoder" "^1.0.1" + "module-error" "^1.0.1" + "queue-microtask" "^1.2.3" + +"adm-zip@^0.4.16": + "integrity" "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" + "resolved" "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz" + "version" "0.4.16" + +"agent-base@6": + "integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==" + "resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + "version" "6.0.2" + dependencies: + "debug" "4" + +"aggregate-error@^3.0.0": + "integrity" "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==" + "resolved" "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "clean-stack" "^2.0.0" + "indent-string" "^4.0.0" + +"ansi-colors@^4.1.1": + "integrity" "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==" + "resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + "version" "4.1.3" + +"ansi-colors@4.1.1": + "integrity" "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + "resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" + "version" "4.1.1" + +"ansi-escapes@^4.3.0": + "integrity" "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==" + "resolved" "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + "version" "4.3.2" + dependencies: + "type-fest" "^0.21.3" + +"ansi-regex@^5.0.1": + "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + "version" "5.0.1" + +"ansi-styles@^3.2.1": + "integrity" "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + "version" "3.2.1" + dependencies: + "color-convert" "^1.9.0" + +"ansi-styles@^4.0.0": + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "color-convert" "^2.0.1" + +"ansi-styles@^4.1.0": + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "color-convert" "^2.0.1" + +"anymatch@~3.1.2": + "integrity" "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==" + "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + "version" "3.1.3" + dependencies: + "normalize-path" "^3.0.0" + "picomatch" "^2.0.4" + +"argparse@^2.0.1": + "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + "version" "2.0.1" + +"async-eventemitter@^0.2.4": + "integrity" "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==" + "resolved" "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz" + "version" "0.2.4" + dependencies: + "async" "^2.4.0" + +"async@^2.4.0": + "integrity" "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==" + "resolved" "https://registry.npmjs.org/async/-/async-2.6.4.tgz" + "version" "2.6.4" + dependencies: + "lodash" "^4.17.14" + +"balanced-match@^1.0.0": + "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + "version" "1.0.2" + +"base-x@^3.0.2": + "integrity" "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==" + "resolved" "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" + "version" "3.0.9" + dependencies: + "safe-buffer" "^5.0.1" + +"base64-js@^1.3.1": + "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + "version" "1.5.1" + +"bigint-crypto-utils@^3.0.23": + "integrity" "sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==" + "resolved" "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz" + "version" "3.1.7" + dependencies: + "bigint-mod-arith" "^3.1.0" + +"bigint-mod-arith@^3.1.0": + "integrity" "sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==" + "resolved" "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz" + "version" "3.1.2" + +"binary-extensions@^2.0.0": + "integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + "version" "2.2.0" + +"blakejs@^1.1.0": + "integrity" "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + "resolved" "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz" + "version" "1.2.1" + +"bn.js@^4.11.0": + "integrity" "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + "version" "4.12.0" + +"bn.js@^4.11.8": + "integrity" "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + "version" "4.12.0" + +"bn.js@^4.11.9": + "integrity" "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + "version" "4.12.0" + +"bn.js@^5.2.0", "bn.js@^5.2.1": + "integrity" "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" + "version" "5.2.1" + +"brace-expansion@^1.1.7": + "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + "version" "1.1.11" + dependencies: + "balanced-match" "^1.0.0" + "concat-map" "0.0.1" + +"brace-expansion@^2.0.1": + "integrity" "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==" + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "balanced-match" "^1.0.0" + +"braces@~3.0.2": + "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "fill-range" "^7.0.1" + +"brorand@^1.1.0": + "integrity" "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + "resolved" "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + "version" "1.1.0" + +"browser-level@^1.0.1": + "integrity" "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==" + "resolved" "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "abstract-level" "^1.0.2" + "catering" "^2.1.1" + "module-error" "^1.0.2" + "run-parallel-limit" "^1.1.0" + +"browser-stdout@1.3.1": + "integrity" "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + "resolved" "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" + "version" "1.3.1" + +"browserify-aes@^1.2.0": + "integrity" "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==" + "resolved" "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "buffer-xor" "^1.0.3" + "cipher-base" "^1.0.0" + "create-hash" "^1.1.0" + "evp_bytestokey" "^1.0.3" + "inherits" "^2.0.1" + "safe-buffer" "^5.0.1" + +"bs58@^4.0.0": + "integrity" "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==" + "resolved" "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "base-x" "^3.0.2" + +"bs58check@^2.1.2": + "integrity" "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==" + "resolved" "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz" + "version" "2.1.2" + dependencies: + "bs58" "^4.0.0" + "create-hash" "^1.1.0" + "safe-buffer" "^5.1.2" + +"buffer-from@^1.0.0": + "integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + "version" "1.1.2" + +"buffer-xor@^1.0.3": + "integrity" "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + "resolved" "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" + "version" "1.0.3" + +"buffer@^6.0.3": + "integrity" "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" + "version" "6.0.3" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.2.1" + +"busboy@^1.6.0": + "integrity" "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==" + "resolved" "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" + "version" "1.6.0" + dependencies: + "streamsearch" "^1.1.0" + +"bytes@3.1.2": + "integrity" "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "resolved" "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + "version" "3.1.2" + +"call-bind@^1.0.0": + "integrity" "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==" + "resolved" "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "function-bind" "^1.1.1" + "get-intrinsic" "^1.0.2" + +"camelcase@^6.0.0": + "integrity" "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + "version" "6.3.0" + +"catering@^2.1.0", "catering@^2.1.1": + "integrity" "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==" + "resolved" "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz" + "version" "2.1.1" + +"chalk@^2.4.2": + "integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + "version" "2.4.2" + dependencies: + "ansi-styles" "^3.2.1" + "escape-string-regexp" "^1.0.5" + "supports-color" "^5.3.0" + +"chalk@^4.1.0": + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "ansi-styles" "^4.1.0" + "supports-color" "^7.1.0" + +"chokidar@^3.4.0", "chokidar@3.5.3": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + dependencies: + "anymatch" "~3.1.2" + "braces" "~3.0.2" + "glob-parent" "~5.1.2" + "is-binary-path" "~2.1.0" + "is-glob" "~4.0.1" + "normalize-path" "~3.0.0" + "readdirp" "~3.6.0" + optionalDependencies: + "fsevents" "~2.3.2" + +"ci-info@^2.0.0": + "integrity" "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + "resolved" "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" + "version" "2.0.0" + +"cipher-base@^1.0.0", "cipher-base@^1.0.1", "cipher-base@^1.0.3": + "integrity" "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==" + "resolved" "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz" + "version" "1.0.4" + dependencies: + "inherits" "^2.0.1" + "safe-buffer" "^5.0.1" + +"classic-level@^1.2.0": + "integrity" "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==" + "resolved" "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "abstract-level" "^1.0.2" + "catering" "^2.1.0" + "module-error" "^1.0.1" + "napi-macros" "~2.0.0" + "node-gyp-build" "^4.3.0" + +"clean-stack@^2.0.0": + "integrity" "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + "resolved" "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + "version" "2.2.0" + +"cliui@^7.0.2": + "integrity" "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==" + "resolved" "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + "version" "7.0.4" + dependencies: + "string-width" "^4.2.0" + "strip-ansi" "^6.0.0" + "wrap-ansi" "^7.0.0" + +"color-convert@^1.9.0": + "integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + "version" "1.9.3" + dependencies: + "color-name" "1.1.3" + +"color-convert@^2.0.1": + "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "color-name" "~1.1.4" + +"color-name@~1.1.4": + "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + "version" "1.1.4" + +"color-name@1.1.3": + "integrity" "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + "version" "1.1.3" + +"command-exists@^1.2.8": + "integrity" "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + "resolved" "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz" + "version" "1.2.9" + +"commander@3.0.2": + "integrity" "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" + "resolved" "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz" + "version" "3.0.2" + +"concat-map@0.0.1": + "integrity" "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + "version" "0.0.1" + +"cookie@^0.4.1": + "integrity" "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + "resolved" "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" + "version" "0.4.2" + +"crc-32@^1.2.0": + "integrity" "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" + "resolved" "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz" + "version" "1.2.2" + +"create-hash@^1.1.0", "create-hash@^1.1.2", "create-hash@^1.2.0": + "integrity" "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==" + "resolved" "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "cipher-base" "^1.0.1" + "inherits" "^2.0.1" + "md5.js" "^1.3.4" + "ripemd160" "^2.0.1" + "sha.js" "^2.4.0" + +"create-hmac@^1.1.4", "create-hmac@^1.1.7": + "integrity" "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==" + "resolved" "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz" + "version" "1.1.7" + dependencies: + "cipher-base" "^1.0.3" + "create-hash" "^1.1.0" + "inherits" "^2.0.1" + "ripemd160" "^2.0.0" + "safe-buffer" "^5.0.1" + "sha.js" "^2.4.8" + +"debug@^4.1.1", "debug@^4.3.3", "debug@4", "debug@4.3.4": + "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + "version" "4.3.4" + dependencies: + "ms" "2.1.2" + +"decamelize@^4.0.0": + "integrity" "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" + "resolved" "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" + "version" "4.0.0" + +"depd@2.0.0": + "integrity" "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "resolved" "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + "version" "2.0.0" + +"diff@5.0.0": + "integrity" "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" + "resolved" "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + "version" "5.0.0" + +"elliptic@^6.5.2", "elliptic@^6.5.4", "elliptic@6.5.4": + "integrity" "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==" + "resolved" "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" + "version" "6.5.4" + dependencies: + "bn.js" "^4.11.9" + "brorand" "^1.1.0" + "hash.js" "^1.0.0" + "hmac-drbg" "^1.0.1" + "inherits" "^2.0.4" + "minimalistic-assert" "^1.0.1" + "minimalistic-crypto-utils" "^1.0.1" + +"emoji-regex@^8.0.0": + "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + "version" "8.0.0" + +"enquirer@^2.3.0": + "integrity" "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==" + "resolved" "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" + "version" "2.3.6" + dependencies: + "ansi-colors" "^4.1.1" + +"env-paths@^2.2.0": + "integrity" "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + "resolved" "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + "version" "2.2.1" + +"escalade@^3.1.1": + "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + "version" "3.1.1" + +"escape-string-regexp@^1.0.5": + "integrity" "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + "version" "1.0.5" + +"escape-string-regexp@4.0.0": + "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + "version" "4.0.0" + +"ethereum-cryptography@^0.1.3": + "integrity" "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==" + "resolved" "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz" + "version" "0.1.3" + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + "blakejs" "^1.1.0" + "browserify-aes" "^1.2.0" + "bs58check" "^2.1.2" + "create-hash" "^1.2.0" + "create-hmac" "^1.1.7" + "hash.js" "^1.1.7" + "keccak" "^3.0.0" + "pbkdf2" "^3.0.17" + "randombytes" "^2.1.0" + "safe-buffer" "^5.1.2" + "scrypt-js" "^3.0.0" + "secp256k1" "^4.0.1" + "setimmediate" "^1.0.5" + +"ethereum-cryptography@^1.0.3": + "integrity" "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==" + "resolved" "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz" + "version" "1.1.2" + dependencies: + "@noble/hashes" "1.1.2" + "@noble/secp256k1" "1.6.3" + "@scure/bip32" "1.1.0" + "@scure/bip39" "1.1.0" + +"ethereum-cryptography@0.1.3": + "integrity" "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==" + "resolved" "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz" + "version" "0.1.3" + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + "blakejs" "^1.1.0" + "browserify-aes" "^1.2.0" + "bs58check" "^2.1.2" + "create-hash" "^1.2.0" + "create-hmac" "^1.1.7" + "hash.js" "^1.1.7" + "keccak" "^3.0.0" + "pbkdf2" "^3.0.17" + "randombytes" "^2.1.0" + "safe-buffer" "^5.1.2" + "scrypt-js" "^3.0.0" + "secp256k1" "^4.0.1" + "setimmediate" "^1.0.5" + +"ethereumjs-abi@^0.6.8": + "integrity" "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==" + "resolved" "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz" + "version" "0.6.8" + dependencies: + "bn.js" "^4.11.8" + "ethereumjs-util" "^6.0.0" + +"ethereumjs-util@^6.0.0", "ethereumjs-util@^6.2.1": + "integrity" "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==" + "resolved" "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz" + "version" "6.2.1" + dependencies: + "@types/bn.js" "^4.11.3" + "bn.js" "^4.11.0" + "create-hash" "^1.1.2" + "elliptic" "^6.5.2" + "ethereum-cryptography" "^0.1.3" + "ethjs-util" "0.1.6" + "rlp" "^2.2.3" + +"ethjs-util@^0.1.6", "ethjs-util@0.1.6": + "integrity" "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==" + "resolved" "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz" + "version" "0.1.6" + dependencies: + "is-hex-prefixed" "1.0.0" + "strip-hex-prefix" "1.0.0" + +"event-target-shim@^5.0.0": + "integrity" "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + "resolved" "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" + "version" "5.0.1" + +"evp_bytestokey@^1.0.3": + "integrity" "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==" + "resolved" "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz" + "version" "1.0.3" + dependencies: + "md5.js" "^1.3.4" + "safe-buffer" "^5.1.1" + +"fill-range@^7.0.1": + "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" + "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "to-regex-range" "^5.0.1" + +"find-up@^2.1.0": + "integrity" "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==" + "resolved" "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "locate-path" "^2.0.0" + +"find-up@5.0.0": + "integrity" "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==" + "resolved" "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "locate-path" "^6.0.0" + "path-exists" "^4.0.0" + +"flat@^5.0.2": + "integrity" "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" + "resolved" "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" + "version" "5.0.2" + +"follow-redirects@^1.12.1": + "integrity" "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" + "version" "1.15.2" + +"fp-ts@^1.0.0", "fp-ts@1.19.3": + "integrity" "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" + "resolved" "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz" + "version" "1.19.3" + +"fs-extra@^0.30.0": + "integrity" "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz" + "version" "0.30.0" + dependencies: + "graceful-fs" "^4.1.2" + "jsonfile" "^2.1.0" + "klaw" "^1.0.0" + "path-is-absolute" "^1.0.0" + "rimraf" "^2.2.8" + +"fs-extra@^7.0.1": + "integrity" "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "graceful-fs" "^4.1.2" + "jsonfile" "^4.0.0" + "universalify" "^0.1.0" + +"fs.realpath@^1.0.0": + "integrity" "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + "version" "1.0.0" + +"fsevents@~2.3.2": + "integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==" + "resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + "version" "2.3.2" + +"function-bind@^1.1.1": + "integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + "version" "1.1.1" + +"functional-red-black-tree@^1.0.1": + "integrity" "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + "resolved" "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + "version" "1.0.1" + +"get-caller-file@^2.0.5": + "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + "version" "2.0.5" + +"get-intrinsic@^1.0.2": + "integrity" "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==" + "resolved" "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz" + "version" "1.1.3" + dependencies: + "function-bind" "^1.1.1" + "has" "^1.0.3" + "has-symbols" "^1.0.3" + +"glob-parent@~5.1.2": + "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==" + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + "version" "5.1.2" + dependencies: + "is-glob" "^4.0.1" + +"glob@^7.1.3", "glob@7.2.0": + "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" + "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + "version" "7.2.0" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^3.0.4" + "once" "^1.3.0" + "path-is-absolute" "^1.0.0" + +"graceful-fs@^4.1.2", "graceful-fs@^4.1.6", "graceful-fs@^4.1.9": + "integrity" "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + "version" "4.2.10" + +"hardhat@^2.12.4": + "integrity" "sha512-rc9S2U/4M+77LxW1Kg7oqMMmjl81tzn5rNFARhbXKUA1am/nhfMJEujOjuKvt+ZGMiZ11PYSe8gyIpB/aRNDgw==" + "resolved" "https://registry.npmjs.org/hardhat/-/hardhat-2.12.4.tgz" + "version" "2.12.4" + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-blockchain" "^6.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-evm" "^1.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-statemanager" "^1.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@nomicfoundation/ethereumjs-vm" "^6.0.0" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + "abort-controller" "^3.0.0" + "adm-zip" "^0.4.16" + "aggregate-error" "^3.0.0" + "ansi-escapes" "^4.3.0" + "chalk" "^2.4.2" + "chokidar" "^3.4.0" + "ci-info" "^2.0.0" + "debug" "^4.1.1" + "enquirer" "^2.3.0" + "env-paths" "^2.2.0" + "ethereum-cryptography" "^1.0.3" + "ethereumjs-abi" "^0.6.8" + "find-up" "^2.1.0" + "fp-ts" "1.19.3" + "fs-extra" "^7.0.1" + "glob" "7.2.0" + "immutable" "^4.0.0-rc.12" + "io-ts" "1.10.4" + "keccak" "^3.0.2" + "lodash" "^4.17.11" + "mnemonist" "^0.38.0" + "mocha" "^10.0.0" + "p-map" "^4.0.0" + "qs" "^6.7.0" + "raw-body" "^2.4.1" + "resolve" "1.17.0" + "semver" "^6.3.0" + "solc" "0.7.3" + "source-map-support" "^0.5.13" + "stacktrace-parser" "^0.1.10" + "tsort" "0.0.1" + "undici" "^5.4.0" + "uuid" "^8.3.2" + "ws" "^7.4.6" + +"has-flag@^3.0.0": + "integrity" "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + "version" "3.0.0" + +"has-flag@^4.0.0": + "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + "version" "4.0.0" + +"has-symbols@^1.0.3": + "integrity" "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + "resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + "version" "1.0.3" + +"has@^1.0.3": + "integrity" "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" + "resolved" "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + "version" "1.0.3" + dependencies: + "function-bind" "^1.1.1" + +"hash-base@^3.0.0": + "integrity" "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==" + "resolved" "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "inherits" "^2.0.4" + "readable-stream" "^3.6.0" + "safe-buffer" "^5.2.0" + +"hash.js@^1.0.0", "hash.js@^1.0.3", "hash.js@^1.1.7", "hash.js@1.1.7": + "integrity" "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==" + "resolved" "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + "version" "1.1.7" + dependencies: + "inherits" "^2.0.3" + "minimalistic-assert" "^1.0.1" + +"he@1.2.0": + "integrity" "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + "resolved" "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + "version" "1.2.0" + +"hmac-drbg@^1.0.1": + "integrity" "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==" + "resolved" "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "hash.js" "^1.0.3" + "minimalistic-assert" "^1.0.0" + "minimalistic-crypto-utils" "^1.0.1" + +"http-errors@2.0.0": + "integrity" "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==" + "resolved" "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "depd" "2.0.0" + "inherits" "2.0.4" + "setprototypeof" "1.2.0" + "statuses" "2.0.1" + "toidentifier" "1.0.1" + +"https-proxy-agent@^5.0.0": + "integrity" "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==" + "resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "agent-base" "6" + "debug" "4" + +"iconv-lite@0.4.24": + "integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==" + "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + "version" "0.4.24" + dependencies: + "safer-buffer" ">= 2.1.2 < 3" + +"ieee754@^1.2.1": + "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + "version" "1.2.1" + +"immutable@^4.0.0-rc.12": + "integrity" "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==" + "resolved" "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz" + "version" "4.1.0" + +"indent-string@^4.0.0": + "integrity" "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + "resolved" "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + "version" "4.0.0" + +"inflight@^1.0.4": + "integrity" "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==" + "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + "version" "1.0.6" + dependencies: + "once" "^1.3.0" + "wrappy" "1" + +"inherits@^2.0.1", "inherits@^2.0.3", "inherits@^2.0.4", "inherits@2", "inherits@2.0.4": + "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + "version" "2.0.4" + +"io-ts@1.10.4": + "integrity" "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==" + "resolved" "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz" + "version" "1.10.4" + dependencies: + "fp-ts" "^1.0.0" + +"is-binary-path@~2.1.0": + "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==" + "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "binary-extensions" "^2.0.0" + +"is-buffer@^2.0.5": + "integrity" "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + "resolved" "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" + "version" "2.0.5" + +"is-extglob@^2.1.1": + "integrity" "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + "version" "2.1.1" + +"is-fullwidth-code-point@^3.0.0": + "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + "version" "3.0.0" + +"is-glob@^4.0.1", "is-glob@~4.0.1": + "integrity" "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==" + "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "is-extglob" "^2.1.1" + +"is-hex-prefixed@1.0.0": + "integrity" "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==" + "resolved" "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz" + "version" "1.0.0" + +"is-number@^7.0.0": + "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + "version" "7.0.0" + +"is-plain-obj@^2.1.0": + "integrity" "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + "resolved" "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" + "version" "2.1.0" + +"is-unicode-supported@^0.1.0": + "integrity" "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + "resolved" "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + "version" "0.1.0" + +"js-sha3@0.8.0": + "integrity" "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "resolved" "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" + "version" "0.8.0" + +"js-yaml@4.1.0": + "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" + "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "argparse" "^2.0.1" + +"jsonfile@^2.1.0": + "integrity" "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz" + "version" "2.4.0" + optionalDependencies: + "graceful-fs" "^4.1.6" + +"jsonfile@^4.0.0": + "integrity" "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" + "version" "4.0.0" + optionalDependencies: + "graceful-fs" "^4.1.6" + +"keccak@^3.0.0", "keccak@^3.0.2": + "integrity" "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==" + "resolved" "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "node-addon-api" "^2.0.0" + "node-gyp-build" "^4.2.0" + "readable-stream" "^3.6.0" + +"klaw@^1.0.0": + "integrity" "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==" + "resolved" "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz" + "version" "1.3.1" + optionalDependencies: + "graceful-fs" "^4.1.9" + +"level-supports@^4.0.0": + "integrity" "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==" + "resolved" "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz" + "version" "4.0.1" + +"level-transcoder@^1.0.1": + "integrity" "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==" + "resolved" "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "buffer" "^6.0.3" + "module-error" "^1.0.1" + +"level@^8.0.0": + "integrity" "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==" + "resolved" "https://registry.npmjs.org/level/-/level-8.0.0.tgz" + "version" "8.0.0" + dependencies: + "browser-level" "^1.0.1" + "classic-level" "^1.2.0" + +"locate-path@^2.0.0": + "integrity" "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==" + "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "p-locate" "^2.0.0" + "path-exists" "^3.0.0" + +"locate-path@^6.0.0": + "integrity" "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==" + "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "p-locate" "^5.0.0" + +"lodash@^4.17.11", "lodash@^4.17.14": + "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + "version" "4.17.21" + +"log-symbols@4.1.0": + "integrity" "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==" + "resolved" "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "chalk" "^4.1.0" + "is-unicode-supported" "^0.1.0" + +"lru_map@^0.3.3": + "integrity" "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" + "resolved" "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz" + "version" "0.3.3" + +"lru-cache@^5.1.1": + "integrity" "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + "version" "5.1.1" + dependencies: + "yallist" "^3.0.2" + +"mcl-wasm@^0.7.1": + "integrity" "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==" + "resolved" "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz" + "version" "0.7.9" + +"md5.js@^1.3.4": + "integrity" "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==" + "resolved" "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz" + "version" "1.3.5" + dependencies: + "hash-base" "^3.0.0" + "inherits" "^2.0.1" + "safe-buffer" "^5.1.2" + +"memory-level@^1.0.0": + "integrity" "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==" + "resolved" "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "abstract-level" "^1.0.0" + "functional-red-black-tree" "^1.0.1" + "module-error" "^1.0.1" + +"memorystream@^0.3.1": + "integrity" "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==" + "resolved" "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz" + "version" "0.3.1" + +"minimalistic-assert@^1.0.0", "minimalistic-assert@^1.0.1": + "integrity" "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "resolved" "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + "version" "1.0.1" + +"minimalistic-crypto-utils@^1.0.1": + "integrity" "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + "resolved" "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + "version" "1.0.1" + +"minimatch@^3.0.4": + "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + "version" "3.1.2" + dependencies: + "brace-expansion" "^1.1.7" + +"minimatch@5.0.1": + "integrity" "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "brace-expansion" "^2.0.1" + +"mnemonist@^0.38.0": + "integrity" "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==" + "resolved" "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz" + "version" "0.38.5" + dependencies: + "obliterator" "^2.0.0" + +"mocha@^10.0.0": + "integrity" "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==" + "resolved" "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz" + "version" "10.2.0" + dependencies: + "ansi-colors" "4.1.1" + "browser-stdout" "1.3.1" + "chokidar" "3.5.3" + "debug" "4.3.4" + "diff" "5.0.0" + "escape-string-regexp" "4.0.0" + "find-up" "5.0.0" + "glob" "7.2.0" + "he" "1.2.0" + "js-yaml" "4.1.0" + "log-symbols" "4.1.0" + "minimatch" "5.0.1" + "ms" "2.1.3" + "nanoid" "3.3.3" + "serialize-javascript" "6.0.0" + "strip-json-comments" "3.1.1" + "supports-color" "8.1.1" + "workerpool" "6.2.1" + "yargs" "16.2.0" + "yargs-parser" "20.2.4" + "yargs-unparser" "2.0.0" + +"module-error@^1.0.1", "module-error@^1.0.2": + "integrity" "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==" + "resolved" "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz" + "version" "1.0.2" + +"ms@2.1.2": + "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + "version" "2.1.2" + +"ms@2.1.3": + "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + "version" "2.1.3" + +"nanoid@3.3.3": + "integrity" "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==" + "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" + "version" "3.3.3" + +"napi-macros@~2.0.0": + "integrity" "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" + "resolved" "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz" + "version" "2.0.0" + +"node-addon-api@^2.0.0": + "integrity" "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + "resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" + "version" "2.0.2" + +"node-gyp-build@^4.2.0", "node-gyp-build@^4.3.0": + "integrity" "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==" + "resolved" "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz" + "version" "4.5.0" + +"normalize-path@^3.0.0", "normalize-path@~3.0.0": + "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + "version" "3.0.0" + +"object-inspect@^1.9.0": + "integrity" "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "resolved" "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" + "version" "1.12.2" + +"obliterator@^2.0.0": + "integrity" "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + "resolved" "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz" + "version" "2.0.4" + +"once@^1.3.0": + "integrity" "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==" + "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "wrappy" "1" + +"os-tmpdir@~1.0.2": + "integrity" "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + "resolved" "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + "version" "1.0.2" + +"p-limit@^1.1.0": + "integrity" "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==" + "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" + "version" "1.3.0" + dependencies: + "p-try" "^1.0.0" + +"p-limit@^3.0.2": + "integrity" "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==" + "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "yocto-queue" "^0.1.0" + +"p-locate@^2.0.0": + "integrity" "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==" + "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "p-limit" "^1.1.0" + +"p-locate@^5.0.0": + "integrity" "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==" + "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "p-limit" "^3.0.2" + +"p-map@^4.0.0": + "integrity" "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==" + "resolved" "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "aggregate-error" "^3.0.0" + +"p-try@^1.0.0": + "integrity" "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==" + "resolved" "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" + "version" "1.0.0" + +"path-exists@^3.0.0": + "integrity" "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + "version" "3.0.0" + +"path-exists@^4.0.0": + "integrity" "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + "version" "4.0.0" + +"path-is-absolute@^1.0.0": + "integrity" "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + "version" "1.0.1" + +"path-parse@^1.0.6": + "integrity" "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "resolved" "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + "version" "1.0.7" + +"pbkdf2@^3.0.17": + "integrity" "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==" + "resolved" "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz" + "version" "3.1.2" + dependencies: + "create-hash" "^1.1.2" + "create-hmac" "^1.1.4" + "ripemd160" "^2.0.1" + "safe-buffer" "^5.0.1" + "sha.js" "^2.4.8" + +"picomatch@^2.0.4", "picomatch@^2.2.1": + "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + "version" "2.3.1" + +"qs@^6.7.0": + "integrity" "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==" + "resolved" "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + "version" "6.11.0" + dependencies: + "side-channel" "^1.0.4" + +"queue-microtask@^1.2.2", "queue-microtask@^1.2.3": + "integrity" "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + "resolved" "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + "version" "1.2.3" + +"randombytes@^2.1.0": + "integrity" "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==" + "resolved" "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "safe-buffer" "^5.1.0" + +"raw-body@^2.4.1": + "integrity" "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==" + "resolved" "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + "version" "2.5.1" + dependencies: + "bytes" "3.1.2" + "http-errors" "2.0.0" + "iconv-lite" "0.4.24" + "unpipe" "1.0.0" + +"readable-stream@^3.6.0": + "integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==" + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "inherits" "^2.0.3" + "string_decoder" "^1.1.1" + "util-deprecate" "^1.0.1" + +"readdirp@~3.6.0": + "integrity" "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==" + "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "picomatch" "^2.2.1" + +"require-directory@^2.1.1": + "integrity" "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + "version" "2.1.1" + +"require-from-string@^2.0.0": + "integrity" "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + "resolved" "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + "version" "2.0.2" + +"resolve@1.17.0": + "integrity" "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==" + "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" + "version" "1.17.0" + dependencies: + "path-parse" "^1.0.6" + +"rimraf@^2.2.8": + "integrity" "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==" + "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" + "version" "2.7.1" + dependencies: + "glob" "^7.1.3" + +"ripemd160@^2.0.0", "ripemd160@^2.0.1": + "integrity" "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==" + "resolved" "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "hash-base" "^3.0.0" + "inherits" "^2.0.1" + +"rlp@^2.2.3": + "integrity" "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==" + "resolved" "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz" + "version" "2.2.7" + dependencies: + "bn.js" "^5.2.0" + +"run-parallel-limit@^1.1.0": + "integrity" "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==" + "resolved" "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "queue-microtask" "^1.2.2" + +"rustbn.js@~0.2.0": + "integrity" "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==" + "resolved" "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz" + "version" "0.2.0" + +"safe-buffer@^5.0.1", "safe-buffer@^5.1.0", "safe-buffer@^5.1.1", "safe-buffer@^5.1.2", "safe-buffer@^5.2.0", "safe-buffer@~5.2.0": + "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + "version" "5.2.1" + +"safer-buffer@>= 2.1.2 < 3": + "integrity" "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "resolved" "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + "version" "2.1.2" + +"scrypt-js@^3.0.0": + "integrity" "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + "resolved" "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz" + "version" "3.0.1" + +"secp256k1@^4.0.1": + "integrity" "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==" + "resolved" "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "elliptic" "^6.5.4" + "node-addon-api" "^2.0.0" + "node-gyp-build" "^4.2.0" + +"semver@^5.5.0": + "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + "version" "5.7.1" + +"semver@^6.3.0": + "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + "version" "6.3.0" + +"serialize-javascript@6.0.0": + "integrity" "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==" + "resolved" "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "randombytes" "^2.1.0" + +"setimmediate@^1.0.5": + "integrity" "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + "resolved" "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + "version" "1.0.5" + +"setprototypeof@1.2.0": + "integrity" "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "resolved" "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + "version" "1.2.0" + +"sha.js@^2.4.0", "sha.js@^2.4.8": + "integrity" "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==" + "resolved" "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" + "version" "2.4.11" + dependencies: + "inherits" "^2.0.1" + "safe-buffer" "^5.0.1" + +"side-channel@^1.0.4": + "integrity" "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==" + "resolved" "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + "version" "1.0.4" + dependencies: + "call-bind" "^1.0.0" + "get-intrinsic" "^1.0.2" + "object-inspect" "^1.9.0" + +"solc@0.7.3": + "integrity" "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==" + "resolved" "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz" + "version" "0.7.3" + dependencies: + "command-exists" "^1.2.8" + "commander" "3.0.2" + "follow-redirects" "^1.12.1" + "fs-extra" "^0.30.0" + "js-sha3" "0.8.0" + "memorystream" "^0.3.1" + "require-from-string" "^2.0.0" + "semver" "^5.5.0" + "tmp" "0.0.33" + +"source-map-support@^0.5.13": + "integrity" "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==" + "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + "version" "0.5.21" + dependencies: + "buffer-from" "^1.0.0" + "source-map" "^0.6.0" + +"source-map@^0.6.0": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" + +"stacktrace-parser@^0.1.10": + "integrity" "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==" + "resolved" "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz" + "version" "0.1.10" + dependencies: + "type-fest" "^0.7.1" + +"statuses@2.0.1": + "integrity" "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + "resolved" "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + "version" "2.0.1" + +"streamsearch@^1.1.0": + "integrity" "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" + "resolved" "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" + "version" "1.1.0" + +"string_decoder@^1.1.1": + "integrity" "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==" + "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + "version" "1.3.0" + dependencies: + "safe-buffer" "~5.2.0" + +"string-width@^4.1.0", "string-width@^4.2.0": + "integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" + "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + "version" "4.2.3" + dependencies: + "emoji-regex" "^8.0.0" + "is-fullwidth-code-point" "^3.0.0" + "strip-ansi" "^6.0.1" + +"strip-ansi@^6.0.0", "strip-ansi@^6.0.1": + "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "ansi-regex" "^5.0.1" + +"strip-hex-prefix@1.0.0": + "integrity" "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==" + "resolved" "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "is-hex-prefixed" "1.0.0" + +"strip-json-comments@3.1.1": + "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + "version" "3.1.1" + +"supports-color@^5.3.0": + "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + "version" "5.5.0" + dependencies: + "has-flag" "^3.0.0" + +"supports-color@^7.1.0": + "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + "version" "7.2.0" + dependencies: + "has-flag" "^4.0.0" + +"supports-color@8.1.1": + "integrity" "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + "version" "8.1.1" + dependencies: + "has-flag" "^4.0.0" + +"tmp@0.0.33": + "integrity" "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==" + "resolved" "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" + "version" "0.0.33" + dependencies: + "os-tmpdir" "~1.0.2" + +"to-regex-range@^5.0.1": + "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" + "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "is-number" "^7.0.0" + +"toidentifier@1.0.1": + "integrity" "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + "resolved" "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + "version" "1.0.1" + +"tslib@^1.9.3": + "integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + "version" "1.14.1" + +"tsort@0.0.1": + "integrity" "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" + "resolved" "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz" + "version" "0.0.1" + +"tweetnacl-util@^0.15.1": + "integrity" "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + "resolved" "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz" + "version" "0.15.1" + +"tweetnacl@^1.0.3": + "integrity" "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "resolved" "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" + "version" "1.0.3" + +"type-fest@^0.21.3": + "integrity" "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + "version" "0.21.3" + +"type-fest@^0.7.1": + "integrity" "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==" + "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz" + "version" "0.7.1" + +"undici@^5.4.0": + "integrity" "sha512-yJlHYw6yXPPsuOH0x2Ib1Km61vu4hLiRRQoafs+WUgX1vO64vgnxiCEN9dpIrhZyHFsai3F0AEj4P9zy19enEQ==" + "resolved" "https://registry.npmjs.org/undici/-/undici-5.14.0.tgz" + "version" "5.14.0" + dependencies: + "busboy" "^1.6.0" + +"universalify@^0.1.0": + "integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + "version" "0.1.2" + +"unpipe@1.0.0": + "integrity" "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "resolved" "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + "version" "1.0.0" + +"util-deprecate@^1.0.1": + "integrity" "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + "version" "1.0.2" + +"uuid@^8.3.2": + "integrity" "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "resolved" "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + "version" "8.3.2" + +"workerpool@6.2.1": + "integrity" "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==" + "resolved" "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" + "version" "6.2.1" + +"wrap-ansi@^7.0.0": + "integrity" "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" + "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "ansi-styles" "^4.0.0" + "string-width" "^4.1.0" + "strip-ansi" "^6.0.0" + +"wrappy@1": + "integrity" "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + "version" "1.0.2" + +"ws@^7.4.6": + "integrity" "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" + "resolved" "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz" + "version" "7.5.9" + +"y18n@^5.0.5": + "integrity" "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "resolved" "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + "version" "5.0.8" + +"yallist@^3.0.2": + "integrity" "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "resolved" "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + "version" "3.1.1" + +"yargs-parser@^20.2.2", "yargs-parser@20.2.4": + "integrity" "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + "version" "20.2.4" + +"yargs-unparser@2.0.0": + "integrity" "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==" + "resolved" "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "camelcase" "^6.0.0" + "decamelize" "^4.0.0" + "flat" "^5.0.2" + "is-plain-obj" "^2.1.0" + +"yargs@16.2.0": + "integrity" "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + "version" "16.2.0" + dependencies: + "cliui" "^7.0.2" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.0" + "y18n" "^5.0.5" + "yargs-parser" "^20.2.2" + +"yocto-queue@^0.1.0": + "integrity" "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + "version" "0.1.0" From 53abf454ca1686a1737831c8b4ebe3ade1573509 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Fri, 31 Mar 2023 17:41:50 +0200 Subject: [PATCH 09/23] updated README with list of properties --- contracts/ERC721/README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/contracts/ERC721/README.md b/contracts/ERC721/README.md index 358a63b..3d8d6e3 100644 --- a/contracts/ERC721/README.md +++ b/contracts/ERC721/README.md @@ -88,26 +88,26 @@ Should cause these properties to fail: ## Properties Tested ### Basic properties -- test_ERC721_transferFromResetApproval -- test_ERC721_transferFromUpdatesOwner -- test_ERC721_transferFromSelf -- test_ERC721_transferFromSelfResetsApproval -- test_ERC721_external_ownerOfInvalidTokenMustRevert -- test_ERC721_external_balanceOfZeroAddressMustRevert -- test_ERC721_external_approvingInvalidTokenMustRevert -- test_ERC721_external_transferFromNotApproved -- test_ERC721_external_transferFromZeroAddress -- test_ERC721_external_transferToZeroAddress -- test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver +- `transferFrom()` should reset approvals +- `transferFrom()` should update the token owner +- `transferFrom()` to self should not break accounting +- `transferFrom()` to self should reset approvals +- `ownerOf()` should revert on invalid token +- `balanceOf()` should revert on address zero +- `approve()` should revert on invalid token +- `transferFrom()` should revert if caller is not operator +- `transferFrom()` should revert if `from` is the zero address +- `transferFrom()` should revert if `to` is the zero address +- `safeTransferFrom()` should revert if receiver is a contract that does not implement `onERC721Received()` ### Mintable properties -- test_ERC721_mintIncreasesSupply -- test_ERC721_mintCreatesFreshToken +- `mint()` should increase the total supply +- `mint()` should correctly assign ownership/account balance and revert if the `tokenId` already exists ### Burnable properties -- test_ERC721_burnReducesTotalSupply -- test_ERC721_burnRevertOnTransferFromPreviousOwner -- test_ERC721_burnRevertOnApprove -- test_ERC721_burnRevertOnOwnerOf -- test_ERC721_burnRevertOnTransferFromZeroAddress -- test_ERC721_burnRevertOnGetApproved \ No newline at end of file +- `burn()` should reduce the total supply +- `burn()` should clear approvals +- cannot `approve()` a burned token +- `ownerOf()` should revert if the token has been burned +- cannot transfer a burned token +- `getApproved()` should revert if the token is burned \ No newline at end of file From 213ed7a421f928ee1644944b5e5959e612235977 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Fri, 31 Mar 2023 18:16:38 +0200 Subject: [PATCH 10/23] updated main readme to include erc721 --- PROPERTIES.md | 37 +++++ README.md | 134 +++++++++++++++++- contracts/ERC721/README.md | 14 +- tests/ERC721/foundry/src/ExampleToken.sol | 8 -- .../ERC721/hardhat/contracts/ExampleToken.sol | 12 +- 5 files changed, 174 insertions(+), 31 deletions(-) diff --git a/PROPERTIES.md b/PROPERTIES.md index 9575ec0..b066bd0 100644 --- a/PROPERTIES.md +++ b/PROPERTIES.md @@ -67,6 +67,43 @@ This file lists all the currently implemented Echidna property tests for ERC20, | ERC20-ALLOWANCE-001 | [test_ERC20_setAndIncreaseAllowance](https://github.com/crytic/properties/blob/main/contracts/ERC20/internal/properties/ERC20IncreaseAllowanceProperties.sol#L17) | Allowance should be updated correctly when `increaseAllowance` is called. | | ERC20-ALLOWANCE-002 | [test_ERC20_setAndDecreaseAllowance](https://github.com/crytic/properties/blob/main/contracts/ERC20/internal/properties/ERC20IncreaseAllowanceProperties.sol#L28) | Allowance should be updated correctly when `decreaseAllowance` is called. | +# ERC721 + +### Basic properties for standard functions + +| ID | Name | Invariant tested | +|---|---|---| +| ERC721-BASE-001 | [test_ERC20_balanceOfZeroAddressMustRevert](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L13) | Calling `balanceOf` for the zero address should revert. | +| ERC721-BASE-002 | [test_ERC721_ownerOfInvalidTokenMustRevert](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L19) | Calling ownerOf for an invalid token should revert. | +| ERC721-BASE-003 | [test_ERC721_approvingInvalidTokenMustRevert](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L26) | `approve()` should revert on invalid token. | +| ERC721-BASE-004 | [test_ERC721_transferFromNotApproved](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L33) | `transferFrom()` should revert if caller is not operator. | +| ERC721-BASE-005 | [test_ERC721_transferFromResetApproval](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L51) | `transferFrom()` should reset approvals. | +| ERC721-BASE-006 | [test_ERC721_transferFromUpdatesOwner](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L67) | `transferFrom()` should update the token owner. | +| ERC721-BASE-007 | [test_ERC721_transferFromZeroAddress](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L81) | `transferFrom()` should revert if `from` is the zero address. | +| ERC721-BASE-008 | [test_ERC721_transferToZeroAddress](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L90) | `transferFrom()` should revert if `to` is the zero address. | +| ERC721-BASE-009 | [test_ERC721_transferFromSelf](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L101) | `transferFrom()` to self should not break accounting. | +| ERC721-BASE-010 | [test_ERC721_transferFromSelfResetsApproval](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L115) | `transferFrom()` to self should reset approvals. | +| ERC721-BASE-011 | [test_ERC721_safeTransferFromRevertsOnNoncontractReceiver](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L128) | `safeTransferFrom()` should revert if receiver is a contract that does not implement `onERC721Received()` | + +### Tests for burnable tokens + +| ID | Name | Invariant tested | +|---|---|---| +| ERC721-BURNABLE-001 | [test_ERC721_burnReducesTotalSupply](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol#L14) | User balance and total supply should be updated correctly when `burn` is called. | +| ERC721-BURNABLE-002 | [test_ERC721_burnRevertOnTransferFromPreviousOwner](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol#L29) | A token that has been burned cannot be transferred. | +| ERC721-BURNABLE-003 | [test_ERC721_burnRevertOnTransferFromZeroAddress](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol#L40) | A token that has been burned cannot be transferred. | +| ERC721-BURNABLE-004 | [test_ERC721_burnRevertOnApprove](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol#L51) | A burned token should have its approvals reset. | +| ERC721-BURNABLE-005 | [test_ERC721_burnRevertOnGetApproved](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol#L62) | `getApproved()` should revert if the token is burned. | +| ERC721-BURNABLE-006 | [test_ERC721_burnRevertOnOwnerOf](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol#L73) | `ownerOf()` should revert if the token has been burned. | + +### Tests for mintable tokens + +| ID | Name | Invariant tested | +|---|---|---| +| ERC721-MINTABLE-001 | [test_ERC721_mintIncreasesSupply](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721MintableProperties.sol#L11) | User balance and total supply should be updated correctly after minting. | +| ERC721-MINTABLE-002 | [test_ERC721_mintCreatesFreshToken](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721MintableProperties.sol#L22) | User balance and total supply should be updated correctly after minting. | + + ## ERC4626 | ID | Name | Invariant tested | diff --git a/README.md b/README.md index a7c7f83..d703e82 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ - [Properties](#properties) - [Testing the properties with fuzzing](#testing-the-properties-with-fuzzing) - [ERC20 tests](#erc20-tests) + - [ERC721 Tests](#erc721-tests) - [ERC4626 Tests](#erc4626-tests) - [ABDKMath64x64 tests](#abdkmath64x64-tests) - [Additional resources](#additional-resources) @@ -23,6 +24,7 @@ This repository contains 168 code properties for: - [ERC20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/) token: mintable, burnable, pausable and transferable invariants ([25 properties](PROPERTIES.md#erc20)). +- [ERC721](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) token: mintable, burnable, and transferable invariants ([19 properties](PROPERTIES.md#erc721)). - [ERC4626](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/) vaults: strict specification and additional security invariants ([37 properties](PROPERTIES.md#erc4626)). - [ABDKMath64x64](https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.md) fixed-point library invariants ([106 properties](PROPERTIES.md#abdkmath64x64)). @@ -55,7 +57,7 @@ To test an ERC20 token, follow these steps: You can see the output for a [compliant token](#example-output-for-a-compliant-token), and [non compliant token](#example-output-for-a-non-compliant-token). #### Integration -Decide if you want to do internal or external testing. Both approaches have advantanges and disadvantages, you can check more information about them [here](https://secure-contracts.com/program-analysis/echidna/basic/common-testing-approaches.html). +Decide if you want to do internal or external testing. Both approaches have advantages and disadvantages, you can check more information about them [here](https://secure-contracts.com/program-analysis/echidna/basic/common-testing-approaches.html). For internal testing, create a new Solidity file containing the `CryticERC20InternalHarness` contract. `USER1`, `USER2` and `USER3` constants are initialized by default in `PropertiesConstants` contract to be the addresses from where echidna sends transactions, and `INITIAL_BALANCE` is by default `1000e18`: ```Solidity @@ -180,13 +182,135 @@ Event sequence: Panic(1), AssertEqFail("Equal assertion failed. Message: Failed ... ``` -### ERC4626 Tests +### ERC721 tests -To test an ERC4626 token, follow these steps: +To test an ERC721 token, follow these steps: 1. [Integration](#integration-1) 2. [Configuration](#configuration-1) 3. [Run](#run-1) +You can see the output for a [compliant token](#example-output-for-a-compliant-token-1), and [non compliant token](#example-output-for-a-non-compliant-token-1). + +#### Integration +Decide if you want to do internal or external testing. Both approaches have advantages and disadvantages, you can check more information about them [here](https://secure-contracts.com/program-analysis/echidna/basic/common-testing-approaches.html). + +For internal testing, create a new Solidity file containing the `CryticERC721InternalHarness` contract. `USER1`, `USER2` and `USER3` constants are initialized by default in `PropertiesConstants` contract to be the addresses from where echidna sends transactions. +```Solidity +pragma solidity ^0.8.0; +import "@crytic/properties/contracts/ERC721/internal/properties/ERC721BasicProperties.sol"; +import "./MyToken.sol"; +contract CryticERC721InternalHarness is MyToken, CryticERC721BasicProperties { + + constructor() { + } +} +``` + +For external testing, create two contracts: the `CryticERC721ExternalHarness` and the `TokenMock` as shown below. +In the `CryticERC721ExternalHarness` contract you can specify which properties to test, via inheritance. In the `TokenMock` contract, you will need to modify the `isMintableOrBurnable` variable if your contract is able to mint or burn tokens. + +```Solidity +pragma solidity ^0.8.0; +import "./MyToken.sol"; +import {ITokenMock} from "@crytic/properties/contracts/ERC721/external/util/ITokenMock.sol"; +import {CryticERC721ExternalBasicProperties} from "@crytic/properties/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol"; +import {PropertiesConstants} from "@crytic/properties/contracts/util/PropertiesConstants.sol"; + + +contract CryticERC721ExternalHarness is CryticERC721ExternalBasicProperties { + constructor() { + // Deploy ERC721 + token = ITokenMock(address(new CryticTokenMock())); + } +} + +contract CryticTokenMock is MyToken, PropertiesConstants { + + bool public isMintableOrBurnable; + + constructor () { + isMintableOrBurnable = true; + } +} +``` + +#### Configuration +Create the following Echidna config file + +```yaml +corpusDir: "tests/crytic/erc721/echidna-corpus-internal" +testMode: assertion +testLimit: 100000 +deployer: "0x10000" +sender: ["0x10000", "0x20000", "0x30000"] +``` + +If you're using external testing, you will also need to specify: + +```yaml +multi-abi: true +``` + +To perform more than one test, save the files with a descriptive path, to identify what test each file or corpus belongs to. For these examples, we use `tests/crytic/erc721/echidna-internal.yaml` and `tests/crytic/erc721/echidna-external.yaml` for the Echidna tests for ERC721. We recommended to modify the `corpusDir` for external tests accordingly. + +The above configuration will start Echidna in assertion mode. Contract will be deployed from address `0x10000`, and transactions will be sent from the owner and two different users (`0x20000` and `0x30000`). There is an initial limit of `100000` tests, but depending on the token code complexity, this can be increased. Finally, once Echidna finishes the fuzzing campaign, corpus and coverage results will be available in the `tests/crytic/erc721/echidna-corpus-internal` directory. + + +#### Run +Run Echidna: +- For internal testing: `echidna-test . --contract CryticERC721InternalHarness --config tests/crytic/erc721/echidna-internal.yaml` +- For external testing: `echidna-test . --contract CryticERC721ExternalHarness --config tests/crytic/erc721/echidna-external.yaml` + +Finally, inspect the coverage report in `tests/crytic/erc721/echidna-corpus-internal` or `tests/crytic/erc721/echidna-corpus-external` when it finishes. + +#### Example: Output for a compliant token + +If the token under test is compliant and no properties will fail during fuzzing, the Echidna output should be similar to the screen below: +``` +$ echidna-test . --contract CryticERC721InternalHarness --config tests/echidna.config.yaml +Loaded total of 23 transactions from corpus/coverage +Analyzing contract: contracts/ERC721/CryticERC721InternalHarness.sol:CryticERC721InternalHarness +name(): passed! 🎉 +test_ERC721_external_transferFromNotApproved(): passed! 🎉 +approve(address,uint256): passed! 🎉 +test_ERC721_external_transferFromUpdatesOwner(): passed! 🎉 +totalSupply(): passed! 🎉 +... +``` + +#### Example: Output for a non-compliant token + +For this example, the ExampleToken's balanceOf function was modified so it does not check that `owner` is the zero address: +``` +function balanceOf(address owner) public view virtual override returns (uint256) { + return _balances[owner]; +} +``` + +In this case, the Echidna output should be similar to the screen below, notice that all functions that rely on `balanceOf()` to work correctly will have their assertions broken, and will report the situation. +``` +$ echidna-test . --contract CryticERC721ExternalHarness --config tests/echidna.config.yaml +Loaded total of 25 transactions from corpus/coverage +Analyzing contract: contracts/ERC721/CryticERC721ExternalHarness.sol:CryticERC721ExternalHarness +name(): passed! 🎉 +test_ERC721_external_transferFromUpdatesOwner(): passed! 🎉 +approve(address,uint256): passed! 🎉 +... +test_ERC721_external_balanceOfZeroAddressMustRevert(): failed!💥 + Call sequence: + test_ERC721_external_balanceOfZeroAddressMustRevert() + +Event sequence: Panic(1), AssertFail("address(0) balance query should have reverted") from: ERC721PropertyTests@0x00a329c0648769A73afAc7F9381E08FB43dBEA72 +... +``` + +### ERC4626 Tests + +To test an ERC4626 token, follow these steps: +1. [Integration](#integration-2) +2. [Configuration](#configuration-2) +3. [Run](#run-2) + #### Integration @@ -255,8 +379,8 @@ A 64.64-bit fixed-point number is a data type that consists of a sign bit, a 63- ABDKMath64x64 library implements [19 arithmetic operations](https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.md#simple-arithmetic "19 arithmetic operations") using fixed-point numbers and [6 conversion functions](https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.md#conversions "6 conversion functions") between integer types and fixed-point types. We provide a number of tests related with fundamental mathematical properties of the floating point numbers. To include these tests into your repository, follow these steps: -1. [Integration](#integration-2) -2. [Run](#run-2) +1. [Integration](#integration-3) +2. [Run](#run-3) #### Integration diff --git a/contracts/ERC721/README.md b/contracts/ERC721/README.md index 3d8d6e3..adb5a64 100644 --- a/contracts/ERC721/README.md +++ b/contracts/ERC721/README.md @@ -41,13 +41,13 @@ Should cause these properties to fail: - test_ERC721_transferFromUpdatesOwner - test_ERC721_transferFromSelf - test_ERC721_transferFromSelfResetsApproval -- test_ERC721_external_ownerOfInvalidTokenMustRevert -- test_ERC721_external_balanceOfZeroAddressMustRevert -- test_ERC721_external_approvingInvalidTokenMustRevert -- test_ERC721_external_transferFromNotApproved -- test_ERC721_external_transferFromZeroAddress -- test_ERC721_external_transferToZeroAddress -- test_ERC721_external_safeTransferFromRevertsOnNoncontractReceiver +- test_ERC721_ownerOfInvalidTokenMustRevert +- test_ERC721_balanceOfZeroAddressMustRevert +- test_ERC721_approvingInvalidTokenMustRevert +- test_ERC721_transferFromNotApproved +- test_ERC721_transferFromZeroAddress +- test_ERC721_transferToZeroAddress +- test_ERC721_safeTransferFromRevertsOnNoncontractReceiver ### Mintable properties diff --git a/tests/ERC721/foundry/src/ExampleToken.sol b/tests/ERC721/foundry/src/ExampleToken.sol index 700bbe5..42abc65 100644 --- a/tests/ERC721/foundry/src/ExampleToken.sol +++ b/tests/ERC721/foundry/src/ExampleToken.sol @@ -9,14 +9,6 @@ import "@openzeppelin/contracts/access/Ownable.sol"; contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable, Pausable, Ownable { constructor() ERC721("Example token", "EXT") {} - function pause() public onlyOwner { - _pause(); - } - - function unpause() public onlyOwner { - _unpause(); - } - function mint(address to, uint256 tokenId) public virtual { _mint(to, tokenId); } diff --git a/tests/ERC721/hardhat/contracts/ExampleToken.sol b/tests/ERC721/hardhat/contracts/ExampleToken.sol index 700bbe5..f20cc98 100644 --- a/tests/ERC721/hardhat/contracts/ExampleToken.sol +++ b/tests/ERC721/hardhat/contracts/ExampleToken.sol @@ -3,20 +3,10 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -import "@openzeppelin/contracts/security/Pausable.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; -contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable, Pausable, Ownable { +contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable { constructor() ERC721("Example token", "EXT") {} - function pause() public onlyOwner { - _pause(); - } - - function unpause() public onlyOwner { - _unpause(); - } - function mint(address to, uint256 tokenId) public virtual { _mint(to, tokenId); } From 266ce39304601e6bea7c29177162029e1660d67c Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Fri, 31 Mar 2023 18:18:54 +0200 Subject: [PATCH 11/23] updated properties.md table of contents --- PROPERTIES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PROPERTIES.md b/PROPERTIES.md index b066bd0..93a5839 100644 --- a/PROPERTIES.md +++ b/PROPERTIES.md @@ -12,6 +12,10 @@ This file lists all the currently implemented Echidna property tests for ERC20, - [Tests for mintable tokens](#tests-for-mintable-tokens) - [Tests for pausable tokens](#tests-for-pausable-tokens) - [Tests for tokens implementing `increaseAllowance` and `decreaseAllowance`](#tests-for-tokens-implementing-increaseallowance-and-decreaseallowance) + - [ERC721](#erc721) + - [Basic properties for standard functions](#basic-properties-for-standard-functions-1) + - [Tests for burnable tokens](#tests-for-burnable-tokens-1) + - [Tests for mintable tokens](#tests-for-mintable-tokens-1) - [ERC4626](#erc4626) - [ABDKMath64x64](#abdkmath64x64) From e8fd26547fee25817b68fda577892af9793aac95 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Mon, 3 Apr 2023 10:38:36 +0200 Subject: [PATCH 12/23] rolled back gitmodules --- .gitmodules | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index ca41865..b039b10 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,11 +1,11 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std - branch = v1.5.2 + branch = v1.1.1 [submodule "lib/solmate"] path = lib/solmate url = https://github.com/transmissions11/solmate - tag = v6 + tag = v6 [submodule "lib/ERC4626"] path = lib/ERC4626 url = https://github.com/fubuloubu/ERC4626 @@ -18,6 +18,3 @@ path = lib/openzeppelin-contracts url = https://github.com/openzeppelin/openzeppelin-contracts branch = v4.8.0 -[submodule "tests/ERC721/foundry/lib/forge-std"] - path = tests/ERC721/foundry/lib/forge-std - url = https://github.com/foundry-rs/forge-std From 20df1304b657503e56e49f4b2cfb0c513e21da53 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Mon, 3 Apr 2023 11:02:36 +0200 Subject: [PATCH 13/23] deleted top level remappings.txt --- remappings.txt | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 remappings.txt diff --git a/remappings.txt b/remappings.txt deleted file mode 100644 index c40d8fe..0000000 --- a/remappings.txt +++ /dev/null @@ -1,6 +0,0 @@ -ERC4626/=lib/ERC4626/contracts/ -ds-test/=lib/forge-std/lib/ds-test/src/ -erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ -forge-std/=lib/forge-std/src/ -@openzeppelin/=lib/openzeppelin-contracts/ -solmate/=lib/solmate/ From 87e0ab6ff05c46193949a148fa46304ddebc0739 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Mon, 3 Apr 2023 12:38:46 +0200 Subject: [PATCH 14/23] fixing ERC721 foundry examples --- tests/ERC721/foundry/src/ExampleToken.sol | 10 +++++-- tests/ERC721/foundry/test/CryticTest.sol | 33 +++++++++++++++++++++ tests/ERC721/foundry/test/CryticTestExt.sol | 11 ++++--- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/tests/ERC721/foundry/src/ExampleToken.sol b/tests/ERC721/foundry/src/ExampleToken.sol index 42abc65..4220cbc 100644 --- a/tests/ERC721/foundry/src/ExampleToken.sol +++ b/tests/ERC721/foundry/src/ExampleToken.sol @@ -7,16 +7,21 @@ import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable, Pausable, Ownable { + + uint256 public counter; constructor() ERC721("Example token", "EXT") {} - function mint(address to, uint256 tokenId) public virtual { - _mint(to, tokenId); + function mint(address to, uint256 amount) public { + for (uint256 i; i < amount; i++) { + _mint(to, counter++); + } } // Overrides function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal + virtual override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); @@ -25,6 +30,7 @@ contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable, Pausable, Own function supportsInterface(bytes4 interfaceId) public view + virtual override(ERC721, ERC721Enumerable) returns (bool) { diff --git a/tests/ERC721/foundry/test/CryticTest.sol b/tests/ERC721/foundry/test/CryticTest.sol index 7916d56..9e76d56 100644 --- a/tests/ERC721/foundry/test/CryticTest.sol +++ b/tests/ERC721/foundry/test/CryticTest.sol @@ -3,7 +3,40 @@ import "properties/ERC721/internal/properties/ERC721BasicProperties.sol"; import "../src/ExampleToken.sol"; contract CryticERC721InternalHarness is ExampleToken, CryticERC721BasicProperties { + using Address for address; + constructor() { + maxSupply = 100; isMintableOrBurnable = true; + hasMaxSupply = false; + safeReceiver = new MockReceiver(true); + unsafeReceiver = new MockReceiver(false); + } + + function _customMint(uint256 amount) internal virtual { + mint(msg.sender, amount); + } + + function _customMaxSupply() internal virtual view returns (uint256) { + return maxSupply; + } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ExampleToken, CryticERC721TestBase) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ExampleToken, CryticERC721TestBase) + returns (bool) + { + return super.supportsInterface(interfaceId); } } diff --git a/tests/ERC721/foundry/test/CryticTestExt.sol b/tests/ERC721/foundry/test/CryticTestExt.sol index 0718610..2da6448 100644 --- a/tests/ERC721/foundry/test/CryticTestExt.sol +++ b/tests/ERC721/foundry/test/CryticTestExt.sol @@ -1,13 +1,16 @@ pragma solidity ^0.8.0; import "../src/ExampleToken.sol"; -import {IERC721Mock} from "properties/ERC721/external/util/IERC721Mock.sol"; -import {CryticERC721ExternalBasicProperties} from "properties/ERC721/external/properties/ERC721xternalBasicProperties.sol"; +import {IERC721Internal} from "properties/ERC721/util/IERC721Internal.sol"; +import {CryticERC721ExternalBasicProperties} from "properties/ERC721/external/properties/ERC721ExternalBasicProperties.sol"; +import {MockReceiver} from "properties/ERC721/external/util/MockReceiver.sol"; contract CryticERC721ExternalHarness is CryticERC721ExternalBasicProperties { - + constructor() { // Deploy ERC721 - token = IERC721Mock(address(new ERC721Mock())); + token = IERC721Internal(address(new ERC721Mock())); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); } } From 083c32fb71106a0ae720f03894692eb795731fd5 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Mon, 3 Apr 2023 12:39:58 +0200 Subject: [PATCH 15/23] fixed ERC721 foundry examples --- .../ERC721/external/util/ERC721ExternalTestBase.sol | 6 +++--- tests/ERC721/hardhat/contracts/CryticTest.sol | 10 +++++++++- tests/ERC721/hardhat/contracts/CryticTestExt.sol | 6 +++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/contracts/ERC721/external/util/ERC721ExternalTestBase.sol b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol index c13656c..6ba1c8f 100644 --- a/contracts/ERC721/external/util/ERC721ExternalTestBase.sol +++ b/contracts/ERC721/external/util/ERC721ExternalTestBase.sol @@ -9,9 +9,9 @@ import {MockReceiver} from "./MockReceiver.sol"; abstract contract CryticERC721ExternalTestBase is PropertiesAsserts, PropertiesConstants { - IERC721Internal token; - MockReceiver mockSafeReceiver; - MockReceiver mockUnsafeReceiver; + IERC721Internal public token; + MockReceiver public mockSafeReceiver; + MockReceiver public mockUnsafeReceiver; constructor() { } diff --git a/tests/ERC721/hardhat/contracts/CryticTest.sol b/tests/ERC721/hardhat/contracts/CryticTest.sol index f7ab13e..f57bb1d 100644 --- a/tests/ERC721/hardhat/contracts/CryticTest.sol +++ b/tests/ERC721/hardhat/contracts/CryticTest.sol @@ -1,9 +1,17 @@ pragma solidity ^0.8.0; import "@crytic/properties/ERC721/internal/properties/ERC721BasicProperties.sol"; -import "../src/ExampleToken.sol"; +import "./ExampleToken.sol"; contract CryticERC721InternalHarness is ExampleToken, CryticERC721BasicProperties { constructor() { isMintableOrBurnable = true; } + + function _customMint(uint256 amount) internal virtual { + mint(amount); + } + + function _customMaxSupply() internal virtual view returns (uint256) { + return maxSupply; + } } diff --git a/tests/ERC721/hardhat/contracts/CryticTestExt.sol b/tests/ERC721/hardhat/contracts/CryticTestExt.sol index 0979389..26a885f 100644 --- a/tests/ERC721/hardhat/contracts/CryticTestExt.sol +++ b/tests/ERC721/hardhat/contracts/CryticTestExt.sol @@ -1,13 +1,13 @@ pragma solidity ^0.8.0; -import "../src/ExampleToken.sol"; -import {IERC721Mock} from "@crytic/properties/ERC721/external/util/IERC721Mock.sol"; +import "./ExampleToken.sol"; +import {IERC721Internal} from "@crytic/properties/ERC721/util/IERC721Internal.sol"; import {CryticERC721ExternalBasicProperties} from "@crytic/properties/ERC721/external/properties/ERC721xternalBasicProperties.sol"; contract CryticERC721ExternalHarness is CryticERC721ExternalBasicProperties { constructor() { // Deploy ERC721 - token = IERC721Mock(address(new ERC721Mock())); + token = IERC721Internal(address(new ERC721Mock())); } } From 1f754a3d0b573e270cec7b2772a501fcae49f6fd Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Mon, 3 Apr 2023 12:43:00 +0200 Subject: [PATCH 16/23] fixes for ERC721 hardhat examples --- tests/ERC721/hardhat/contracts/CryticTest.sol | 27 ++++++++++++++++++- .../hardhat/contracts/CryticTestExt.sol | 3 +++ .../ERC721/hardhat/contracts/ExampleToken.sol | 10 +++++-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/tests/ERC721/hardhat/contracts/CryticTest.sol b/tests/ERC721/hardhat/contracts/CryticTest.sol index f57bb1d..afb735b 100644 --- a/tests/ERC721/hardhat/contracts/CryticTest.sol +++ b/tests/ERC721/hardhat/contracts/CryticTest.sol @@ -3,15 +3,40 @@ import "@crytic/properties/ERC721/internal/properties/ERC721BasicProperties.sol" import "./ExampleToken.sol"; contract CryticERC721InternalHarness is ExampleToken, CryticERC721BasicProperties { + using Address for address; + constructor() { + maxSupply = 100; isMintableOrBurnable = true; + hasMaxSupply = false; + safeReceiver = new MockReceiver(true); + unsafeReceiver = new MockReceiver(false); } function _customMint(uint256 amount) internal virtual { - mint(amount); + mint(msg.sender, amount); } function _customMaxSupply() internal virtual view returns (uint256) { return maxSupply; } + + // The following functions are overrides required by Solidity. + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + virtual + override(ExampleToken, CryticERC721TestBase) + { + super._beforeTokenTransfer(from, to, tokenId, batchSize); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ExampleToken, CryticERC721TestBase) + returns (bool) + { + return super.supportsInterface(interfaceId); + } } diff --git a/tests/ERC721/hardhat/contracts/CryticTestExt.sol b/tests/ERC721/hardhat/contracts/CryticTestExt.sol index 26a885f..89c6a0b 100644 --- a/tests/ERC721/hardhat/contracts/CryticTestExt.sol +++ b/tests/ERC721/hardhat/contracts/CryticTestExt.sol @@ -2,12 +2,15 @@ pragma solidity ^0.8.0; import "./ExampleToken.sol"; import {IERC721Internal} from "@crytic/properties/ERC721/util/IERC721Internal.sol"; import {CryticERC721ExternalBasicProperties} from "@crytic/properties/ERC721/external/properties/ERC721xternalBasicProperties.sol"; +import {MockReceiver} from "properties/ERC721/external/util/MockReceiver.sol"; contract CryticERC721ExternalHarness is CryticERC721ExternalBasicProperties { constructor() { // Deploy ERC721 token = IERC721Internal(address(new ERC721Mock())); + mockSafeReceiver = new MockReceiver(true); + mockUnsafeReceiver = new MockReceiver(false); } } diff --git a/tests/ERC721/hardhat/contracts/ExampleToken.sol b/tests/ERC721/hardhat/contracts/ExampleToken.sol index f20cc98..676b625 100644 --- a/tests/ERC721/hardhat/contracts/ExampleToken.sol +++ b/tests/ERC721/hardhat/contracts/ExampleToken.sol @@ -5,16 +5,21 @@ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable { + + uint256 public counter; constructor() ERC721("Example token", "EXT") {} - function mint(address to, uint256 tokenId) public virtual { - _mint(to, tokenId); + function mint(address to, uint256 amount) public { + for (uint256 i; i < amount; i++) { + _mint(to, counter++); + } } // Overrides function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal + virtual override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); @@ -23,6 +28,7 @@ contract ExampleToken is ERC721, ERC721Enumerable, ERC721Burnable { function supportsInterface(bytes4 interfaceId) public view + virtual override(ERC721, ERC721Enumerable) returns (bool) { From fa00876202ca803fb30ea7046575939e50d0dea0 Mon Sep 17 00:00:00 2001 From: tuturu-tech <9058533+tuturu-tech@users.noreply.github.com> Date: Mon, 3 Apr 2023 12:45:11 +0200 Subject: [PATCH 17/23] Update .gitmodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index b039b10..ac2a919 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,7 +5,7 @@ [submodule "lib/solmate"] path = lib/solmate url = https://github.com/transmissions11/solmate - tag = v6 + tag = v6 [submodule "lib/ERC4626"] path = lib/ERC4626 url = https://github.com/fubuloubu/ERC4626 From 7988cbe78eff4e26adb061ee0f04cb5314456dd0 Mon Sep 17 00:00:00 2001 From: tuturu-tech <9058533+tuturu-tech@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:13:47 +0200 Subject: [PATCH 18/23] Updated ERC721-BASE-001 in PROPERTIES.md --- PROPERTIES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PROPERTIES.md b/PROPERTIES.md index 3f9b88f..a51acbc 100644 --- a/PROPERTIES.md +++ b/PROPERTIES.md @@ -77,7 +77,7 @@ This file lists all the currently implemented Echidna property tests for ERC20, | ID | Name | Invariant tested | |---|---|---| -| ERC721-BASE-001 | [test_ERC20_balanceOfZeroAddressMustRevert](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L13) | Calling `balanceOf` for the zero address should revert. | +| ERC721-BASE-001 | [test_ERC721_balanceOfZeroAddressMustRevert](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L13) | Calling `balanceOf` for the zero address should revert. | | ERC721-BASE-002 | [test_ERC721_ownerOfInvalidTokenMustRevert](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L19) | Calling ownerOf for an invalid token should revert. | | ERC721-BASE-003 | [test_ERC721_approvingInvalidTokenMustRevert](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L26) | `approve()` should revert on invalid token. | | ERC721-BASE-004 | [test_ERC721_transferFromNotApproved](https://github.com/crytic/properties/blob/main/contracts/ERC721/internal/properties/ERC721BasicProperties.sol#L33) | `transferFrom()` should revert if caller is not operator. | From 13a58991ef64b6b3b9f59cf89fbf683d5c155ad3 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Mon, 3 Apr 2023 18:22:08 +0200 Subject: [PATCH 19/23] fixing internal/external setup, added check for underflow, used prank to simplify preconditions for external testing --- .../ERC721ExternalBasicProperties.sol | 34 ++++++++----------- .../ERC721ExternalBurnableProperties.sol | 11 +++++- .../properties/ERC721BasicProperties.sol | 21 ++---------- .../properties/ERC721BurnableProperties.sol | 4 +-- .../ERC721/internal/util/ERC721TestBase.sol | 1 + 5 files changed, 28 insertions(+), 43 deletions(-) diff --git a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol index 29207b3..b0ccaff 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol @@ -1,6 +1,7 @@ pragma solidity ^0.8.13; import "../util/ERC721ExternalTestBase.sol"; +import "../../../util/Hevm.sol"; abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTestBase { using Address for address; @@ -48,12 +49,12 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes require(target != address(this)); require(target != msg.sender); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = token.isApprovedForAll(msg.sender, address(this)); - address approved = token.getApproved(tokenId); - require(approved == address(this) || isApproved); - token.transferFrom(msg.sender, target, tokenId); + hevm.prank(msg.sender); + token.approve(address(this), tokenId); - approved = token.getApproved(tokenId); + token.transferFrom(msg.sender, target, tokenId); + + address approved = token.getApproved(tokenId); assertWithMsg(approved == address(0), "Approval was not reset"); } @@ -64,9 +65,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes require(target != address(this)); require(target != msg.sender); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = token.isApprovedForAll(msg.sender, address(this)); - address approved = token.getApproved(tokenId); - require(approved == address(this) || isApproved); + hevm.prank(msg.sender); token.transferFrom(msg.sender, target, tokenId); assertWithMsg(token.ownerOf(tokenId) == target, "Token owner not updated"); @@ -87,6 +86,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes require(selfBalance > 0); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + hevm.prank(msg.sender); token.transferFrom(msg.sender, address(0), tokenId); assertWithMsg(false, "Transfer to zero address should have reverted"); @@ -97,9 +97,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes uint256 selfBalance = token.balanceOf(msg.sender); require(selfBalance > 0); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = token.isApprovedForAll(msg.sender, address(this)); - address approved = token.getApproved(tokenId); - require(approved == address(this) || isApproved); + hevm.prank(msg.sender); token.transferFrom(msg.sender, msg.sender, tokenId); assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); @@ -111,9 +109,10 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes uint256 selfBalance = token.balanceOf(msg.sender); require(selfBalance > 0); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = token.isApprovedForAll(msg.sender, address(this)); - address approved = token.getApproved(tokenId); - require(approved == address(this) || isApproved); + require(token.ownerOf(tokenId) == msg.sender); + + hevm.prank(msg.sender); + token.approve(address(this), tokenId); token.transferFrom(msg.sender, msg.sender, tokenId); assertWithMsg(token.getApproved(tokenId) == address(0), "Self transfer does not reset approvals"); @@ -124,15 +123,10 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes uint256 selfBalance = token.balanceOf(msg.sender); require(selfBalance > 0); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = token.isApprovedForAll(msg.sender, address(this)); - address approved = token.getApproved(tokenId); - require(approved == address(this) || isApproved); + hevm.prank(msg.sender); token.safeTransferFrom(msg.sender, address(mockUnsafeReceiver), tokenId); assertWithMsg(false, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); } - // todo test_ERC721_external_setApprovalForAllWorksAsExpected - // todo safeTransferFrom checks - } diff --git a/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol index 8bc2000..e616d5c 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol @@ -1,6 +1,7 @@ pragma solidity ^0.8.13; import "../util/ERC721ExternalTestBase.sol"; +import "../../../util/Hevm.sol"; abstract contract CryticERC721ExternalBurnableProperties is CryticERC721ExternalTestBase { using Address for address; @@ -17,9 +18,11 @@ abstract contract CryticERC721ExternalBurnableProperties is CryticERC721External for(uint256 i; i < selfBalance; i++) { uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + hevm.prank(msg.sender); token.burn(tokenId); } - + // Check for underflow + assertWithMsg(selfBalance <= oldTotalSupply, "Underflow - user balance larger than total supply"); assertEq(oldTotalSupply - selfBalance, token.totalSupply(), "Incorrect supply update on burn"); } @@ -30,7 +33,9 @@ abstract contract CryticERC721ExternalBurnableProperties is CryticERC721External require(selfBalance > 0); uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + hevm.prank(msg.sender); token.burn(tokenId); + hevm.prank(msg.sender); token.safeTransferFrom(msg.sender, target, tokenId); assertWithMsg(false, "Transferring a burned token didn't revert"); } @@ -41,7 +46,9 @@ abstract contract CryticERC721ExternalBurnableProperties is CryticERC721External require(selfBalance > 0); uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + hevm.prank(msg.sender); token.burn(tokenId); + hevm.prank(msg.sender); token.approve(address(this), tokenId); assertWithMsg(false, "Approving a burned token didn't revert"); } @@ -52,6 +59,7 @@ abstract contract CryticERC721ExternalBurnableProperties is CryticERC721External require(selfBalance > 0); uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + hevm.prank(msg.sender); token.burn(tokenId); token.getApproved(tokenId); assertWithMsg(false, "getApproved didn't revert for burned token"); @@ -63,6 +71,7 @@ abstract contract CryticERC721ExternalBurnableProperties is CryticERC721External require(selfBalance > 0); uint256 tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + hevm.prank(msg.sender); token.burn(tokenId); token.ownerOf(tokenId); assertWithMsg(false, "ownerOf didn't revert for burned token"); diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol index 710ad59..766f0ae 100644 --- a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -36,9 +36,7 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != address(this)); require(target != msg.sender); uint tokenId = tokenOfOwnerByIndex(target, 0); - bool isApproved = isApprovedForAll(target, address(this)); - address approved = getApproved(tokenId); - require(approved != address(this) && !isApproved); + _approve(address(0), tokenId); require(ownerOf(tokenId) == target); transferFrom(target, msg.sender, tokenId); @@ -54,12 +52,9 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != address(this)); require(target != msg.sender); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = isApprovedForAll(msg.sender, address(this)); - address approved = getApproved(tokenId); - require(approved == address(this) || isApproved); transferFrom(msg.sender, target, tokenId); - approved = getApproved(tokenId); + address approved = getApproved(tokenId); assertWithMsg(approved == address(0), "Approval was not reset"); } @@ -70,9 +65,6 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != address(this)); require(target != msg.sender); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = isApprovedForAll(msg.sender, address(this)); - address approved = getApproved(tokenId); - require(approved == address(this) || isApproved); transferFrom(msg.sender, target, tokenId); assertWithMsg(ownerOf(tokenId) == target, "Token owner not updated"); @@ -102,9 +94,6 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { uint256 selfBalance = balanceOf(msg.sender); require(selfBalance > 0); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = isApprovedForAll(msg.sender, address(this)); - address approved = getApproved(tokenId); - require(approved == address(this) || isApproved); transferFrom(msg.sender, msg.sender, tokenId); assertWithMsg(ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); @@ -116,9 +105,6 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { uint256 selfBalance = balanceOf(msg.sender); require(selfBalance > 0); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = isApprovedForAll(msg.sender, address(this)); - address approved = getApproved(tokenId); - require(approved == address(this) || isApproved); transferFrom(msg.sender, msg.sender, tokenId); assertWithMsg(getApproved(tokenId) == address(0), "Self transfer does not reset approvals"); @@ -131,9 +117,6 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != address(this)); require(target != msg.sender); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - bool isApproved = isApprovedForAll(msg.sender, address(this)); - address approved = getApproved(tokenId); - require(approved == address(this) || isApproved); require(ownerOf(tokenId) == msg.sender); safeTransferFrom(msg.sender, address(unsafeReceiver), tokenId); diff --git a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol index 020f65c..1359192 100644 --- a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol @@ -22,6 +22,7 @@ abstract contract CryticERC721BurnableProperties is CryticERC721TestBase, ERC721 burn(tokenId); } + assertWithMsg(selfBalance <= oldTotalSupply, "Underflow - user balance larger than total supply"); assertEq(oldTotalSupply - selfBalance, totalSupply(), "Incorrect supply update on burn"); } @@ -81,9 +82,6 @@ abstract contract CryticERC721BurnableProperties is CryticERC721TestBase, ERC721 assertWithMsg(false, "ownerOf didn't revert for burned token"); } - - // todo burned token cannot be minted again - // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) diff --git a/contracts/ERC721/internal/util/ERC721TestBase.sol b/contracts/ERC721/internal/util/ERC721TestBase.sol index c1093c4..53c4393 100644 --- a/contracts/ERC721/internal/util/ERC721TestBase.sol +++ b/contracts/ERC721/internal/util/ERC721TestBase.sol @@ -5,6 +5,7 @@ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "../../../util/PropertiesConstants.sol"; import "../../../util/PropertiesHelper.sol"; import {MockReceiver} from "./MockReceiver.sol"; +import "../../../util/Hevm.sol"; abstract contract CryticERC721TestBase is ERC721, ERC721Enumerable, PropertiesAsserts, PropertiesConstants { From 65051cdba257eb6d42cdedd38452969ca88589e9 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Mon, 3 Apr 2023 18:42:14 +0200 Subject: [PATCH 20/23] fix internal ERC721Compliant double variable definition --- contracts/ERC721/internal/test/standard/ERC721Compliant.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol index 349b208..476f58a 100644 --- a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol +++ b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol @@ -9,7 +9,6 @@ import {MockReceiver} from "../../util/MockReceiver.sol"; contract ERC721Compliant is CryticERC721InternalPropertyTests { uint256 public counter; - uint256 public maxSupply; constructor() ERC721("ERC721Compliant","Compliant") { isMintableOrBurnable = true; From 59ed2d718fd908175ad59a0e99392cdf6ed63ac0 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Tue, 4 Apr 2023 15:16:34 +0200 Subject: [PATCH 21/23] updated the way minting is done to improve performance --- contracts/ERC721/README.md | 6 ++-- .../ERC721ExternalBasicProperties.sol | 5 +++ .../ERC721ExternalMintableProperties.sol | 27 +++++++-------- .../ERC721/external/test/ERC721Compliant.sol | 9 ++--- .../ERC721/external/test/echidna.config.yaml | 2 +- .../external/util/ERC721IncorrectBasic.sol | 10 +++--- .../external/util/ERC721IncorrectBurnable.sol | 10 +++--- .../external/util/ERC721IncorrectMintable.sol | 10 +++--- .../properties/ERC721BasicProperties.sol | 6 ++-- .../properties/ERC721BurnableProperties.sol | 4 +-- .../properties/ERC721MintableProperties.sol | 33 +++++++------------ .../test/standard/ERC721BasicTests.sol | 16 ++++----- .../test/standard/ERC721BurnableTests.sol | 6 ++-- .../test/standard/ERC721Compliant.sol | 10 +++--- .../test/standard/ERC721MintableTests.sol | 8 ++--- contracts/ERC721/util/IERC721Internal.sol | 2 +- 16 files changed, 70 insertions(+), 94 deletions(-) diff --git a/contracts/ERC721/README.md b/contracts/ERC721/README.md index adb5a64..0c4bb6d 100644 --- a/contracts/ERC721/README.md +++ b/contracts/ERC721/README.md @@ -77,12 +77,12 @@ Should cause these properties to fail: ### Vanilla OpenZeppelin ERC721 -- Internal: -`echidna ./contracts/ERC721/internal/test/standard/ERC721Compliant.sol --contract ERC721Compliant --config ./contracts/ERC721/internal/test/echidna.config.yaml` - - External: `echidna ./contracts/ERC721/external/test/standard/ERC721CompliantTests.sol --contract TestHarness --config ./contracts/ERC721/external/test/echidna.config.yaml` +- Internal: +`echidna ./contracts/ERC721/internal/test/standard/ERC721Compliant.sol --contract ERC721Compliant --config ./contracts/ERC721/internal/test/echidna.config.yaml` + [EIP-721 Spec](https://eips.ethereum.org/EIPS/eip-721) ## Properties Tested diff --git a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol index b0ccaff..a6ee4e4 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol @@ -40,6 +40,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes token.transferFrom(msg.sender, target, tokenId); assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Transferred a token without being approved."); + assertWithMsg(false, "transferFrom without approval did not revert"); } // transferFrom should reset approval for that token @@ -48,10 +49,13 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes require(selfBalance > 0); require(target != address(this)); require(target != msg.sender); + uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); + hevm.prank(msg.sender); token.approve(address(this), tokenId); + token.transferFrom(msg.sender, target, tokenId); address approved = token.getApproved(tokenId); @@ -78,6 +82,7 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes token.transferFrom(address(0), target, tokenId); assertWithMsg(token.ownerOf(tokenId) != target, "Transfered from zero address"); + assertWithMsg(false, "transferFrom does not revert when `from` is the zero-address"); } // Transfers to the zero address should revert diff --git a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol index 0fece1e..0ab7d6a 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol @@ -8,32 +8,27 @@ abstract contract CryticERC721ExternalMintableProperties is CryticERC721External //////////////////////////////////////// // Properties // mint increases the total supply - function test_ERC721_external_mintIncreasesSupply(uint256 amount) public virtual { + function test_ERC721_external_mintIncreasesSupply() public virtual { require(token.isMintableOrBurnable()); - require(amount > 0); uint256 selfBalance = token.balanceOf(address(this)); uint256 oldTotalSupply = token.totalSupply(); - token._customMint(address(this), amount); + token._customMint(address(this)); - assertEq(oldTotalSupply + amount, token.totalSupply(), "Total supply was not correctly increased"); - assertEq(selfBalance + amount, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); + assertEq(oldTotalSupply + 1, token.totalSupply(), "Total supply was not correctly increased"); + assertEq(selfBalance + 1, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); } // mint creates a fresh token - function test_ERC721_external_mintCreatesFreshToken(uint256 amount) public virtual { + function test_ERC721_external_mintCreatesFreshToken() public virtual { require(token.isMintableOrBurnable()); - require(amount > 0); uint256 selfBalance = token.balanceOf(address(this)); - uint256 endIndex = selfBalance + amount; - token._customMint(address(this), amount); + token._customMint(address(this)); - for(uint256 i = selfBalance; i < endIndex; i++) { - uint256 tokenId = token.tokenOfOwnerByIndex(address(this), i); - assertWithMsg(token.ownerOf(tokenId) == address(this), "Token ID was not minted to receiver"); - assertWithMsg(!usedId[tokenId], "Token ID minted is not new"); - usedId[tokenId] = true; - } + uint256 tokenId = token.tokenOfOwnerByIndex(address(this), selfBalance); + assertWithMsg(token.ownerOf(tokenId) == address(this), "Token ID was not minted to receiver"); + assertWithMsg(!usedId[tokenId], "Token ID minted is not new"); + usedId[tokenId] = true; - assertEq(selfBalance + amount, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); + assertEq(selfBalance + 1, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); } } diff --git a/contracts/ERC721/external/test/ERC721Compliant.sol b/contracts/ERC721/external/test/ERC721Compliant.sol index 02c6517..a5cf97b 100644 --- a/contracts/ERC721/external/test/ERC721Compliant.sol +++ b/contracts/ERC721/external/test/ERC721Compliant.sol @@ -15,12 +15,9 @@ contract ERC721Compliant is ERC721, ERC721Enumerable { } - function _customMint(address to, uint256 amount) public virtual { - maxSupply += amount; - for (uint256 i; i < amount; i++) { - _mint(to, counter++); - } - + function _customMint(address to) public virtual { + maxSupply += 1; + _mint(to, counter++); } function _customMaxSupply() public virtual view returns (uint256) { diff --git a/contracts/ERC721/external/test/echidna.config.yaml b/contracts/ERC721/external/test/echidna.config.yaml index 6b3e570..3b5b31d 100644 --- a/contracts/ERC721/external/test/echidna.config.yaml +++ b/contracts/ERC721/external/test/echidna.config.yaml @@ -1,5 +1,5 @@ coverage: true -multi-abi: true +allContracts: true corpusDir: "corpus" testMode: assertion testLimit: 100000 diff --git a/contracts/ERC721/external/util/ERC721IncorrectBasic.sol b/contracts/ERC721/external/util/ERC721IncorrectBasic.sol index 8bcf84e..ca45bf0 100644 --- a/contracts/ERC721/external/util/ERC721IncorrectBasic.sol +++ b/contracts/ERC721/external/util/ERC721IncorrectBasic.sol @@ -64,14 +64,12 @@ contract ERC721IncorrectBasic is Context, ERC165, IERC721, IERC721Metadata { isMintableOrBurnable = true; } - function mint(address to, uint256 amount) public { - for(uint256 i; i < amount; i++) { - _mint(to, counter++); - } + function mint(address to) public { + _mint(to, counter++); } - function _customMint(address to, uint256 amount) external { - mint(to, amount); + function _customMint(address to) external { + mint(to); } function _customMaxSupply() external view returns (uint256) { diff --git a/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol b/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol index 2dd8d59..8c44951 100644 --- a/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol +++ b/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol @@ -64,10 +64,8 @@ contract ERC721IncorrectBurnable is Context, ERC165, IERC721, IERC721Metadata { isMintableOrBurnable = true; } - function mint(address to, uint256 amount) public { - for(uint256 i; i < amount; i++) { - _mint(to, counter++); - } + function mint(address to) public { + _mint(to, counter++); } function burn(uint256 tokenId) public virtual { @@ -76,8 +74,8 @@ contract ERC721IncorrectBurnable is Context, ERC165, IERC721, IERC721Metadata { _burn(tokenId); } - function _customMint(address to, uint256 amount) external { - mint(to, amount); + function _customMint(address to) external { + mint(to); } function _customMaxSupply() external view returns (uint256) { diff --git a/contracts/ERC721/external/util/ERC721IncorrectMintable.sol b/contracts/ERC721/external/util/ERC721IncorrectMintable.sol index ffa4ea3..d78e690 100644 --- a/contracts/ERC721/external/util/ERC721IncorrectMintable.sol +++ b/contracts/ERC721/external/util/ERC721IncorrectMintable.sol @@ -64,14 +64,12 @@ contract ERC721IncorrectMintable is Context, ERC165, IERC721, IERC721Metadata { isMintableOrBurnable = true; } - function mint(address to, uint256 amount) public { - for(uint256 i; i < amount; i++) { - _mint(to, counter++); - } + function mint(address to) public { + _mint(to, counter++); } - function _customMint(address to, uint256 amount) external { - mint(to, amount); + function _customMint(address to) external { + mint(to); } function _customMaxSupply() external view returns (uint256) { diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol index 766f0ae..df16e24 100644 --- a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -37,6 +37,7 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != msg.sender); uint tokenId = tokenOfOwnerByIndex(target, 0); _approve(address(0), tokenId); + _setApprovalForAll(target, msg.sender, false); require(ownerOf(tokenId) == target); transferFrom(target, msg.sender, tokenId); @@ -75,7 +76,8 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != msg.sender); transferFrom(address(0), target, tokenId); - assertWithMsg(ownerOf(tokenId) != target, "Transfered from zero address"); + assertWithMsg(ownerOf(tokenId) != target, "Transfered from zero address minted the token"); + assertWithMsg(false, "Transfer from zero address did not revert"); } // Transfers to the zero address should revert @@ -86,7 +88,7 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { transferFrom(msg.sender, address(0), tokenId); - assertWithMsg(ownerOf(tokenId) == address(0), "Transfer to zero address should have reverted"); + assertWithMsg(false, "Transfer to zero address should have reverted"); } // Transfers to self should not break accounting diff --git a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol index 1359192..924d351 100644 --- a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol @@ -11,7 +11,7 @@ abstract contract CryticERC721BurnableProperties is CryticERC721TestBase, ERC721 // Properties // The burn function should destroy tokens and reduce the total supply - function test_ERC721_burnReducesTotalSupply(uint256 tokenId) public virtual { + function test_ERC721_burnReducesTotalSupply() public virtual { require(isMintableOrBurnable); uint256 selfBalance = balanceOf(msg.sender); require(selfBalance > 0); @@ -44,7 +44,7 @@ abstract contract CryticERC721BurnableProperties is CryticERC721TestBase, ERC721 require(selfBalance > 0); uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); - burn(tokenId); + _burn(tokenId); transferFrom(address(0), target, tokenId); assertWithMsg(false, "Transferring a burned token didn't revert"); } diff --git a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol index 89d6967..22c6884 100644 --- a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol @@ -8,41 +8,30 @@ abstract contract CryticERC721MintableProperties is CryticERC721TestBase { //////////////////////////////////////// // Properties // mint increases the total supply - function test_ERC721_mintIncreasesSupply(uint256 amount) public virtual { + function test_ERC721_mintIncreasesSupply() public virtual { require(isMintableOrBurnable); uint256 selfBalance = balanceOf(msg.sender); uint256 oldTotalSupply = totalSupply(); - _customMint(amount); + _customMint(msg.sender); - assertEq(oldTotalSupply + amount, totalSupply(), "Total supply was not correctly increased"); - assertEq(selfBalance + amount, balanceOf(msg.sender), "Receiver supply was not correctly increased"); + assertEq(oldTotalSupply + 1, totalSupply(), "Total supply was not correctly increased"); + assertEq(selfBalance + 1, balanceOf(msg.sender), "Receiver supply was not correctly increased"); } // mint creates a fresh token - function test_ERC721_mintCreatesFreshToken(uint256 amount) public virtual { + function test_ERC721_mintCreatesFreshToken() public virtual { require(isMintableOrBurnable); uint256 selfBalance = balanceOf(msg.sender); - uint256 endIndex = selfBalance + amount; - _customMint(amount); + _customMint(msg.sender); - assertEq(selfBalance + amount, balanceOf(msg.sender), "Receiver supply was not correctly increased"); + assertEq(selfBalance + 1, balanceOf(msg.sender), "Receiver supply was not correctly increased"); - for(uint256 i = selfBalance; i < endIndex; i++) { - uint256 tokenId = tokenOfOwnerByIndex(msg.sender, i); - assertWithMsg(ownerOf(tokenId) == msg.sender, "Token ID was not minted to receiver"); - } - } - - // the total supply should never be larger than the max supply - function test_ERC721_totalSupplyShouldNotBeLargerThanMax() public virtual { - require(hasMaxSupply); - uint256 max = _customMaxSupply(); - uint256 total = totalSupply(); - - assertWithMsg(total <= max, "Total supply larger than max"); + uint256 tokenId = tokenOfOwnerByIndex(msg.sender, selfBalance); + assertWithMsg(ownerOf(tokenId) == msg.sender, "Token ID was not minted to receiver"); + } // Wrappers - function _customMint(uint256 amount) internal virtual; + function _customMint(address to) internal virtual; function _customMaxSupply() internal virtual view returns (uint256); } diff --git a/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol b/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol index e10a39e..60d5700 100644 --- a/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol +++ b/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol @@ -18,11 +18,9 @@ contract ERC721BasicTestsInternal is CryticERC721BasicProperties { unsafeReceiver = new MockReceiver(false); } - function mint(uint256 amount) public { + function mint(address to) public { //require(totalSupply() + amount <= maxSupply); - for (uint256 i; i < amount; i++) { - _mint(msg.sender, counter++); - } + _mint(to, counter++); } function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { @@ -47,10 +45,10 @@ contract ERC721BasicTestsInternal is CryticERC721BasicProperties { function transferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { //solhint-disable-next-line max-line-length //require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); - if (from == address(0)) { - _mint(to, tokenId); + if (from == to) { + _mint(to, counter++); } - _approve(address(this), tokenId); + } function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override(ERC721, IERC721) { @@ -90,8 +88,8 @@ contract ERC721BasicTestsInternal is CryticERC721BasicProperties { return super.supportsInterface(interfaceId); } - function _customMint(uint256 amount) internal virtual { - mint(amount); + function _customMint(address to) internal virtual { + mint(to); } function _customMaxSupply() internal virtual view returns (uint256) { diff --git a/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol b/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol index db958df..1554313 100644 --- a/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol +++ b/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol @@ -18,11 +18,9 @@ contract ERC721BurnableTestsInternal is CryticERC721BurnableProperties { unsafeReceiver = new MockReceiver(false); } - function burn(uint256 amount) public virtual override { + function burn(uint256 tokenId) public virtual override { //require(totalSupply() + amount <= maxSupply); - for (uint256 i; i < amount; i++) { - _mint(msg.sender, counter++); - } + _mint(msg.sender, counter++); } function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { diff --git a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol index 476f58a..f23fabf 100644 --- a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol +++ b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol @@ -18,11 +18,9 @@ contract ERC721Compliant is CryticERC721InternalPropertyTests { } - function mint(uint256 amount) public { + function mint(address to) public { //require(totalSupply() + amount <= maxSupply); - for (uint256 i; i < amount; i++) { - _mint(msg.sender, counter++); - } + _mint(to, counter++); } // The following functions are overrides required by Solidity. @@ -44,8 +42,8 @@ contract ERC721Compliant is CryticERC721InternalPropertyTests { return super.supportsInterface(interfaceId); } - function _customMint(uint256 amount) internal virtual override { - mint(amount); + function _customMint(address to) internal virtual override { + mint(to); } function _customMaxSupply() internal virtual override view returns (uint256) { diff --git a/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol b/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol index 5d8649a..65482ed 100644 --- a/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol +++ b/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol @@ -11,14 +11,14 @@ contract ERC721MintableTestsInternal is CryticERC721MintableProperties { uint256 public counter; constructor() ERC721("ERC721BasicTestsInternal","ERC721BasicTestsInternal") { - maxSupply = 100; + maxSupply = 10; isMintableOrBurnable = true; hasMaxSupply = false; safeReceiver = new MockReceiver(true); unsafeReceiver = new MockReceiver(false); } - function mint(uint256 amount) public { + function mint(address to) public { //require(totalSupply() + amount <= maxSupply); /* for (uint256 i; i < amount; i++) { _mint(msg.sender, counter++); @@ -90,8 +90,8 @@ contract ERC721MintableTestsInternal is CryticERC721MintableProperties { return super.supportsInterface(interfaceId); } - function _customMint(uint256 amount) internal virtual override { - mint(amount); + function _customMint(address to) internal virtual override { + mint(to); } function _customMaxSupply() internal virtual override view returns (uint256) { diff --git a/contracts/ERC721/util/IERC721Internal.sol b/contracts/ERC721/util/IERC721Internal.sol index aeddad6..5fdb162 100644 --- a/contracts/ERC721/util/IERC721Internal.sol +++ b/contracts/ERC721/util/IERC721Internal.sol @@ -6,6 +6,6 @@ import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; interface IERC721Internal is IERC721, IERC721Enumerable { function isMintableOrBurnable() external returns (bool); function burn(uint256 tokenId) external; - function _customMint(address to, uint256 amount) external; + function _customMint(address to) external; function _customMaxSupply() external view returns (uint256); } \ No newline at end of file From c3b32305c2726ebd1ef9e2ba191ade2dc6a13c0f Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Tue, 4 Apr 2023 17:49:49 +0200 Subject: [PATCH 22/23] cleaning up ERC721 properties, using try/catch for edge cases --- .../ERC721ExternalBasicProperties.sol | 25 ++++++----- .../ERC721ExternalBurnableProperties.sol | 4 +- .../ERC721ExternalMintableProperties.sol | 27 ++++++----- .../ERC721/external/test/ERC721Compliant.sol | 16 +++---- .../test/standard/ERC721BasicTests.sol | 2 +- .../test/standard/ERC721BurnableTests.sol | 2 +- .../test/standard/ERC721MintableTests.sol | 2 +- .../external/util/ERC721IncorrectBasic.sol | 6 --- .../external/util/ERC721IncorrectBurnable.sol | 6 --- .../external/util/ERC721IncorrectMintable.sol | 11 ++--- .../ERC721/external/util/IERC721Mock.sol | 10 ----- .../ERC721/external/util/MockReceiver.sol | 1 - .../properties/ERC721BasicProperties.sol | 45 +++++++++++-------- .../properties/ERC721BurnableProperties.sol | 2 +- .../properties/ERC721MintableProperties.sol | 1 - .../test/standard/ERC721BasicTests.sol | 6 --- .../test/standard/ERC721BurnableTests.sol | 8 ++-- .../test/standard/ERC721Compliant.sol | 5 --- .../test/standard/ERC721MintableTests.sol | 6 --- .../ERC721/internal/util/ERC721TestBase.sol | 2 - contracts/ERC721/util/IERC721Internal.sol | 2 +- 21 files changed, 77 insertions(+), 112 deletions(-) delete mode 100644 contracts/ERC721/external/util/IERC721Mock.sol diff --git a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol index a6ee4e4..a877ecd 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBasicProperties.sol @@ -39,7 +39,6 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes require(approved != address(this) && !isApproved); token.transferFrom(msg.sender, target, tokenId); - assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Transferred a token without being approved."); assertWithMsg(false, "transferFrom without approval did not revert"); } @@ -54,8 +53,6 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes hevm.prank(msg.sender); token.approve(address(this), tokenId); - - token.transferFrom(msg.sender, target, tokenId); address approved = token.getApproved(tokenId); @@ -69,19 +66,19 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes require(target != address(this)); require(target != msg.sender); uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); - hevm.prank(msg.sender); - token.transferFrom(msg.sender, target, tokenId); - assertWithMsg(token.ownerOf(tokenId) == target, "Token owner not updated"); + hevm.prank(msg.sender); + try token.transferFrom(msg.sender, target, tokenId) { + assertWithMsg(token.ownerOf(tokenId) == target, "Token owner not updated"); + } catch { + assertWithMsg(false, "transferFrom unexpectedly reverted"); + } } // transfer from zero address should revert function test_ERC721_external_transferFromZeroAddress(address target, uint256 tokenId) public virtual { - require(target != address(this)); - require(target != msg.sender); token.transferFrom(address(0), target, tokenId); - assertWithMsg(token.ownerOf(tokenId) != target, "Transfered from zero address"); assertWithMsg(false, "transferFrom does not revert when `from` is the zero-address"); } @@ -104,9 +101,13 @@ abstract contract CryticERC721ExternalBasicProperties is CryticERC721ExternalTes uint tokenId = token.tokenOfOwnerByIndex(msg.sender, 0); hevm.prank(msg.sender); - token.transferFrom(msg.sender, msg.sender, tokenId); - assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); - assertEq(token.balanceOf(msg.sender), selfBalance, "Self transfer breaks accounting"); + try token.transferFrom(msg.sender, msg.sender, tokenId) { + assertWithMsg(token.ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); + assertEq(token.balanceOf(msg.sender), selfBalance, "Self transfer breaks accounting"); + } catch { + assertWithMsg(false, "transferFrom unexpectedly reverted"); + } + } // Transfer to self reset approval diff --git a/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol index e616d5c..a4f8d5a 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalBurnableProperties.sol @@ -36,7 +36,7 @@ abstract contract CryticERC721ExternalBurnableProperties is CryticERC721External hevm.prank(msg.sender); token.burn(tokenId); hevm.prank(msg.sender); - token.safeTransferFrom(msg.sender, target, tokenId); + token.transferFrom(msg.sender, target, tokenId); assertWithMsg(false, "Transferring a burned token didn't revert"); } @@ -76,6 +76,4 @@ abstract contract CryticERC721ExternalBurnableProperties is CryticERC721External token.ownerOf(tokenId); assertWithMsg(false, "ownerOf didn't revert for burned token"); } - - // todo burned token cannot be minted again } diff --git a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol index 0ab7d6a..3010202 100644 --- a/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol +++ b/contracts/ERC721/external/properties/ERC721ExternalMintableProperties.sol @@ -4,7 +4,7 @@ import "../util/ERC721ExternalTestBase.sol"; abstract contract CryticERC721ExternalMintableProperties is CryticERC721ExternalTestBase { using Address for address; - mapping (uint256 => bool) usedId; + //////////////////////////////////////// // Properties // mint increases the total supply @@ -12,23 +12,26 @@ abstract contract CryticERC721ExternalMintableProperties is CryticERC721External require(token.isMintableOrBurnable()); uint256 selfBalance = token.balanceOf(address(this)); uint256 oldTotalSupply = token.totalSupply(); - token._customMint(address(this)); - assertEq(oldTotalSupply + 1, token.totalSupply(), "Total supply was not correctly increased"); - assertEq(selfBalance + 1, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); + try token._customMint(address(this)) { + assertEq(oldTotalSupply + 1, token.totalSupply(), "Total supply was not correctly increased"); + assertEq(selfBalance + 1, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); + } catch { + assertWithMsg(false, "Minting unexpectedly reverted"); + } } // mint creates a fresh token function test_ERC721_external_mintCreatesFreshToken() public virtual { require(token.isMintableOrBurnable()); uint256 selfBalance = token.balanceOf(address(this)); - token._customMint(address(this)); - - uint256 tokenId = token.tokenOfOwnerByIndex(address(this), selfBalance); - assertWithMsg(token.ownerOf(tokenId) == address(this), "Token ID was not minted to receiver"); - assertWithMsg(!usedId[tokenId], "Token ID minted is not new"); - usedId[tokenId] = true; - - assertEq(selfBalance + 1, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); + try token._customMint(address(this)) { + uint256 tokenId = token.tokenOfOwnerByIndex(address(this), selfBalance); + assertWithMsg(token.ownerOf(tokenId) == address(this), "Token ID was not minted to receiver"); + assertWithMsg(!token.usedId(tokenId), "Token ID minted is not new"); + assertEq(selfBalance + 1, token.balanceOf(address(this)), "Receiver supply was not correctly increased"); + } catch { + assertWithMsg(false, "Minting unexpectedly reverted"); + } } } diff --git a/contracts/ERC721/external/test/ERC721Compliant.sol b/contracts/ERC721/external/test/ERC721Compliant.sol index a5cf97b..18e87e8 100644 --- a/contracts/ERC721/external/test/ERC721Compliant.sol +++ b/contracts/ERC721/external/test/ERC721Compliant.sol @@ -2,27 +2,25 @@ pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; +import {IERC721Internal} from "../../util/IERC721Internal.sol"; -contract ERC721Compliant is ERC721, ERC721Enumerable { +contract ERC721Compliant is ERC721, ERC721Enumerable, IERC721Internal { uint256 public counter; - uint256 public maxSupply; bool public isMintableOrBurnable; + mapping(uint256 => bool) public usedId; constructor() ERC721("OZERC721","OZ") { - maxSupply = 100; isMintableOrBurnable = true; } + function burn(uint256 tokenId) public virtual { + _burn(tokenId); + } function _customMint(address to) public virtual { - maxSupply += 1; _mint(to, counter++); } - - function _customMaxSupply() public virtual view returns (uint256) { - return maxSupply; - } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) @@ -37,7 +35,7 @@ contract ERC721Compliant is ERC721, ERC721Enumerable { public view virtual - override(ERC721, ERC721Enumerable) + override(ERC721, ERC721Enumerable, IERC165) returns (bool) { return super.supportsInterface(interfaceId); diff --git a/contracts/ERC721/external/test/standard/ERC721BasicTests.sol b/contracts/ERC721/external/test/standard/ERC721BasicTests.sol index 14caa5b..10a2820 100644 --- a/contracts/ERC721/external/test/standard/ERC721BasicTests.sol +++ b/contracts/ERC721/external/test/standard/ERC721BasicTests.sol @@ -5,7 +5,7 @@ import {ERC721IncorrectBasic} from "../../util/ERC721IncorrectBasic.sol"; import {IERC721Internal} from "../../../util/IERC721Internal.sol"; import {MockReceiver} from "../../util/MockReceiver.sol"; -contract TestHarness is CryticERC721ExternalBasicProperties { +contract TestHarness is CryticERC721ExternalBasicProperties { constructor() { token = IERC721Internal(address(new ERC721IncorrectBasic("ERC721BAD","ERC721BAD"))); mockSafeReceiver = new MockReceiver(true); diff --git a/contracts/ERC721/external/test/standard/ERC721BurnableTests.sol b/contracts/ERC721/external/test/standard/ERC721BurnableTests.sol index a19b98d..56923b9 100644 --- a/contracts/ERC721/external/test/standard/ERC721BurnableTests.sol +++ b/contracts/ERC721/external/test/standard/ERC721BurnableTests.sol @@ -5,7 +5,7 @@ import {ERC721IncorrectBurnable} from "../../util/ERC721IncorrectBurnable.sol"; import {IERC721Internal} from "../../../util/IERC721Internal.sol"; import {MockReceiver} from "../../util/MockReceiver.sol"; -contract TestHarness is CryticERC721ExternalBurnableProperties { +contract TestHarness is CryticERC721ExternalBurnableProperties { constructor() { token = IERC721Internal(address(new ERC721IncorrectBurnable("ERC721BAD","ERC721BAD"))); mockSafeReceiver = new MockReceiver(true); diff --git a/contracts/ERC721/external/test/standard/ERC721MintableTests.sol b/contracts/ERC721/external/test/standard/ERC721MintableTests.sol index 6fb16a5..8a7fd75 100644 --- a/contracts/ERC721/external/test/standard/ERC721MintableTests.sol +++ b/contracts/ERC721/external/test/standard/ERC721MintableTests.sol @@ -5,7 +5,7 @@ import {ERC721IncorrectMintable} from "../../util/ERC721IncorrectMintable.sol"; import {IERC721Internal} from "../../../util/IERC721Internal.sol"; import {MockReceiver} from "../../util/MockReceiver.sol"; -contract TestHarness is CryticERC721ExternalMintableProperties { +contract TestHarness is CryticERC721ExternalMintableProperties { constructor() { token = IERC721Internal(address(new ERC721IncorrectMintable("ERC721BAD","ERC721BAD"))); mockSafeReceiver = new MockReceiver(true); diff --git a/contracts/ERC721/external/util/ERC721IncorrectBasic.sol b/contracts/ERC721/external/util/ERC721IncorrectBasic.sol index ca45bf0..6c19de2 100644 --- a/contracts/ERC721/external/util/ERC721IncorrectBasic.sol +++ b/contracts/ERC721/external/util/ERC721IncorrectBasic.sol @@ -25,7 +25,6 @@ contract ERC721IncorrectBasic is Context, ERC165, IERC721, IERC721Metadata { // Token symbol string private _symbol; - uint256 public maxSupply; uint256 public counter; bool public isMintableOrBurnable; address excluded = address(0x10000); @@ -60,7 +59,6 @@ contract ERC721IncorrectBasic is Context, ERC165, IERC721, IERC721Metadata { constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; - maxSupply = 100; isMintableOrBurnable = true; } @@ -72,10 +70,6 @@ contract ERC721IncorrectBasic is Context, ERC165, IERC721, IERC721Metadata { mint(to); } - function _customMaxSupply() external view returns (uint256) { - return maxSupply; - } - /** * @dev See {IERC165-supportsInterface}. */ diff --git a/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol b/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol index 8c44951..c20de44 100644 --- a/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol +++ b/contracts/ERC721/external/util/ERC721IncorrectBurnable.sol @@ -25,7 +25,6 @@ contract ERC721IncorrectBurnable is Context, ERC165, IERC721, IERC721Metadata { // Token symbol string private _symbol; - uint256 public maxSupply; uint256 public counter; bool public isMintableOrBurnable; address excluded = address(0x10000); @@ -60,7 +59,6 @@ contract ERC721IncorrectBurnable is Context, ERC165, IERC721, IERC721Metadata { constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; - maxSupply = 100; isMintableOrBurnable = true; } @@ -78,10 +76,6 @@ contract ERC721IncorrectBurnable is Context, ERC165, IERC721, IERC721Metadata { mint(to); } - function _customMaxSupply() external view returns (uint256) { - return maxSupply; - } - /** * @dev See {IERC165-supportsInterface}. */ diff --git a/contracts/ERC721/external/util/ERC721IncorrectMintable.sol b/contracts/ERC721/external/util/ERC721IncorrectMintable.sol index d78e690..071d276 100644 --- a/contracts/ERC721/external/util/ERC721IncorrectMintable.sol +++ b/contracts/ERC721/external/util/ERC721IncorrectMintable.sol @@ -25,10 +25,10 @@ contract ERC721IncorrectMintable is Context, ERC165, IERC721, IERC721Metadata { // Token symbol string private _symbol; - uint256 public maxSupply; uint256 public counter; bool public isMintableOrBurnable; address excluded = address(0x10000); + mapping (uint256 => bool) public usedId; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; @@ -60,22 +60,19 @@ contract ERC721IncorrectMintable is Context, ERC165, IERC721, IERC721Metadata { constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; - maxSupply = 100; isMintableOrBurnable = true; } function mint(address to) public { - _mint(to, counter++); + uint256 id = counter++; + usedId[id] = true; + _mint(to, id); } function _customMint(address to) external { mint(to); } - function _customMaxSupply() external view returns (uint256) { - return maxSupply; - } - /** * @dev See {IERC165-supportsInterface}. */ diff --git a/contracts/ERC721/external/util/IERC721Mock.sol b/contracts/ERC721/external/util/IERC721Mock.sol deleted file mode 100644 index 3b13957..0000000 --- a/contracts/ERC721/external/util/IERC721Mock.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma solidity ^0.8.13; - -import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; - -interface IERC721Mock is IERC721, IERC721Enumerable { - function isMintableOrBurnable() external returns (bool); - - function burn(uint256 tokenId) external; -} \ No newline at end of file diff --git a/contracts/ERC721/external/util/MockReceiver.sol b/contracts/ERC721/external/util/MockReceiver.sol index 618ac84..7c1ab48 100644 --- a/contracts/ERC721/external/util/MockReceiver.sol +++ b/contracts/ERC721/external/util/MockReceiver.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; - contract MockReceiver is ERC721Holder { bool shouldReceive; diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol index df16e24..ff0ec7e 100644 --- a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -41,9 +41,7 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(ownerOf(tokenId) == target); transferFrom(target, msg.sender, tokenId); - assertWithMsg(ownerOf(tokenId) == target, "Target"); - assertWithMsg(ownerOf(tokenId) == msg.sender, "Transferred a token without being approved."); - + assertWithMsg(false, "using transferFrom without being approved should have reverted"); } // transferFrom should reset approval for that token @@ -53,10 +51,14 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != address(this)); require(target != msg.sender); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - transferFrom(msg.sender, target, tokenId); - address approved = getApproved(tokenId); - assertWithMsg(approved == address(0), "Approval was not reset"); + hevm.prank(msg.sender); + try IERC721(address(this)).transferFrom(msg.sender, target, tokenId) { + address approved = getApproved(tokenId); + assertWithMsg(approved == address(0), "Approval was not reset"); + } catch { + assertWithMsg(false, "transferFrom unexpectedly reverted"); + } } // transferFrom correctly updates owner @@ -66,9 +68,13 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != address(this)); require(target != msg.sender); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - transferFrom(msg.sender, target, tokenId); - assertWithMsg(ownerOf(tokenId) == target, "Token owner not updated"); + hevm.prank(msg.sender); + try IERC721(address(this)).transferFrom(msg.sender, target, tokenId) { + assertWithMsg(ownerOf(tokenId) == target, "Token owner not updated"); + } catch { + assertWithMsg(false, "transferFrom unexpectedly reverted"); + } } function test_ERC721_transferFromZeroAddress(address target, uint256 tokenId) public virtual { @@ -76,7 +82,6 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(target != msg.sender); transferFrom(address(0), target, tokenId); - assertWithMsg(ownerOf(tokenId) != target, "Transfered from zero address minted the token"); assertWithMsg(false, "Transfer from zero address did not revert"); } @@ -97,9 +102,13 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(selfBalance > 0); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - transferFrom(msg.sender, msg.sender, tokenId); - assertWithMsg(ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); - assertEq(balanceOf(msg.sender), selfBalance, "Self transfer breaks accounting"); + hevm.prank(msg.sender); + try IERC721(address(this)).transferFrom(msg.sender, msg.sender, tokenId) { + assertWithMsg(ownerOf(tokenId) == msg.sender, "Self transfer changes owner"); + assertEq(balanceOf(msg.sender), selfBalance, "Self transfer breaks accounting"); + } catch { + assertWithMsg(false, "transferFrom unexpectedly reverted"); + } } // Transfer to self reset approval @@ -108,8 +117,12 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(selfBalance > 0); uint tokenId = tokenOfOwnerByIndex(msg.sender, 0); - transferFrom(msg.sender, msg.sender, tokenId); - assertWithMsg(getApproved(tokenId) == address(0), "Self transfer does not reset approvals"); + hevm.prank(msg.sender); + try IERC721(address(this)).transferFrom(msg.sender, msg.sender, tokenId) { + assertWithMsg(getApproved(tokenId) == address(0), "Self transfer does not reset approvals"); + } catch { + assertWithMsg(false, "transferFrom unexpectedly reverted"); + } } // safeTransferFrom reverts if receiver does not implement the callback @@ -124,8 +137,4 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { safeTransferFrom(msg.sender, address(unsafeReceiver), tokenId); assertWithMsg(ownerOf(tokenId) == msg.sender, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); } - - // todo test_ERC721_setApprovalForAllWorksAsExpected - // todo safeTransferFrom checks - } diff --git a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol index 924d351..2ab2767 100644 --- a/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BurnableProperties.sol @@ -44,7 +44,7 @@ abstract contract CryticERC721BurnableProperties is CryticERC721TestBase, ERC721 require(selfBalance > 0); uint256 tokenId = tokenOfOwnerByIndex(msg.sender, 0); - _burn(tokenId); + burn(tokenId); transferFrom(address(0), target, tokenId); assertWithMsg(false, "Transferring a burned token didn't revert"); } diff --git a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol index 22c6884..ec259ef 100644 --- a/contracts/ERC721/internal/properties/ERC721MintableProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721MintableProperties.sol @@ -33,5 +33,4 @@ abstract contract CryticERC721MintableProperties is CryticERC721TestBase { // Wrappers function _customMint(address to) internal virtual; - function _customMaxSupply() internal virtual view returns (uint256); } diff --git a/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol b/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol index 60d5700..9202c5a 100644 --- a/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol +++ b/contracts/ERC721/internal/test/standard/ERC721BasicTests.sol @@ -11,9 +11,7 @@ contract ERC721BasicTestsInternal is CryticERC721BasicProperties { uint256 public counter; constructor() ERC721("ERC721BasicTestsInternal","ERC721BasicTestsInternal") { - maxSupply = 100; isMintableOrBurnable = true; - hasMaxSupply = false; safeReceiver = new MockReceiver(true); unsafeReceiver = new MockReceiver(false); } @@ -91,10 +89,6 @@ contract ERC721BasicTestsInternal is CryticERC721BasicProperties { function _customMint(address to) internal virtual { mint(to); } - - function _customMaxSupply() internal virtual view returns (uint256) { - return maxSupply; - } } contract TestHarness is ERC721BasicTestsInternal { diff --git a/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol b/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol index 1554313..09d2042 100644 --- a/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol +++ b/contracts/ERC721/internal/test/standard/ERC721BurnableTests.sol @@ -11,16 +11,18 @@ contract ERC721BurnableTestsInternal is CryticERC721BurnableProperties { uint256 public counter; constructor() ERC721("ERC721BasicTestsInternal","ERC721BasicTestsInternal") { - maxSupply = 100; isMintableOrBurnable = true; - hasMaxSupply = false; safeReceiver = new MockReceiver(true); unsafeReceiver = new MockReceiver(false); } function burn(uint256 tokenId) public virtual override { //require(totalSupply() + amount <= maxSupply); - _mint(msg.sender, counter++); + if (tokenId % 2 == 0) { + _mint(msg.sender, counter++); + } else { + _burn(tokenId); + } } function balanceOf(address owner) public view virtual override(ERC721, IERC721) returns (uint256) { diff --git a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol index f23fabf..d14ca70 100644 --- a/contracts/ERC721/internal/test/standard/ERC721Compliant.sol +++ b/contracts/ERC721/internal/test/standard/ERC721Compliant.sol @@ -12,7 +12,6 @@ contract ERC721Compliant is CryticERC721InternalPropertyTests { constructor() ERC721("ERC721Compliant","Compliant") { isMintableOrBurnable = true; - maxSupply = 100; safeReceiver = new MockReceiver(true); unsafeReceiver = new MockReceiver(false); @@ -45,8 +44,4 @@ contract ERC721Compliant is CryticERC721InternalPropertyTests { function _customMint(address to) internal virtual override { mint(to); } - - function _customMaxSupply() internal virtual override view returns (uint256) { - return maxSupply; - } } \ No newline at end of file diff --git a/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol b/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol index 65482ed..d6af5ed 100644 --- a/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol +++ b/contracts/ERC721/internal/test/standard/ERC721MintableTests.sol @@ -11,9 +11,7 @@ contract ERC721MintableTestsInternal is CryticERC721MintableProperties { uint256 public counter; constructor() ERC721("ERC721BasicTestsInternal","ERC721BasicTestsInternal") { - maxSupply = 10; isMintableOrBurnable = true; - hasMaxSupply = false; safeReceiver = new MockReceiver(true); unsafeReceiver = new MockReceiver(false); } @@ -93,10 +91,6 @@ contract ERC721MintableTestsInternal is CryticERC721MintableProperties { function _customMint(address to) internal virtual override { mint(to); } - - function _customMaxSupply() internal virtual override view returns (uint256) { - return maxSupply; - } } contract TestHarness is ERC721MintableTestsInternal { diff --git a/contracts/ERC721/internal/util/ERC721TestBase.sol b/contracts/ERC721/internal/util/ERC721TestBase.sol index 53c4393..b9c15c0 100644 --- a/contracts/ERC721/internal/util/ERC721TestBase.sol +++ b/contracts/ERC721/internal/util/ERC721TestBase.sol @@ -11,8 +11,6 @@ abstract contract CryticERC721TestBase is ERC721, ERC721Enumerable, PropertiesAs // Is the contract allowed to change its total supply? bool isMintableOrBurnable; - bool hasMaxSupply; - uint256 maxSupply; MockReceiver safeReceiver; MockReceiver unsafeReceiver; diff --git a/contracts/ERC721/util/IERC721Internal.sol b/contracts/ERC721/util/IERC721Internal.sol index 5fdb162..09ddd44 100644 --- a/contracts/ERC721/util/IERC721Internal.sol +++ b/contracts/ERC721/util/IERC721Internal.sol @@ -6,6 +6,6 @@ import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; interface IERC721Internal is IERC721, IERC721Enumerable { function isMintableOrBurnable() external returns (bool); function burn(uint256 tokenId) external; + function usedId(uint256 tokenId) external view returns (bool); function _customMint(address to) external; - function _customMaxSupply() external view returns (uint256); } \ No newline at end of file From 5b899a5eb4508a694e61dc28bc900c77c2da7d81 Mon Sep 17 00:00:00 2001 From: tuturu-tech Date: Tue, 4 Apr 2023 18:38:30 +0200 Subject: [PATCH 23/23] update property to assert(false) --- contracts/ERC721/internal/properties/ERC721BasicProperties.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol index ff0ec7e..af7eb3e 100644 --- a/contracts/ERC721/internal/properties/ERC721BasicProperties.sol +++ b/contracts/ERC721/internal/properties/ERC721BasicProperties.sol @@ -135,6 +135,6 @@ abstract contract CryticERC721BasicProperties is CryticERC721TestBase { require(ownerOf(tokenId) == msg.sender); safeTransferFrom(msg.sender, address(unsafeReceiver), tokenId); - assertWithMsg(ownerOf(tokenId) == msg.sender, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); + assertWithMsg(false, "safeTransferFrom does not revert if receiver does not implement ERC721.onERC721Received"); } }