From de24c414cf221bfb458c42b61a879e8ef650d85e Mon Sep 17 00:00:00 2001 From: dmfxyz Date: Sat, 23 Mar 2024 15:27:27 -0400 Subject: [PATCH] implement differential and unit tests for complete merkle --- .github/workflows/run_tests.yml | 10 +- .gitignore | 1 + .../scripts/generate_complete_proof.ts | 24 + .../scripts/generate_complete_root.ts | 9 + .../scripts/package-lock.json | 1189 ++++++++++++++--- differential_testing/scripts/package.json | 7 +- .../test/CompleteDifferentialTests.t.sol | 87 ++ src/CompleteMerkle.sol | 3 +- src/test/CompleteMerkle.t.sol | 109 ++ src/test/OZMerkle.t.sol | 167 --- 10 files changed, 1259 insertions(+), 347 deletions(-) create mode 100644 differential_testing/scripts/generate_complete_proof.ts create mode 100644 differential_testing/scripts/generate_complete_root.ts create mode 100644 differential_testing/test/CompleteDifferentialTests.t.sol create mode 100644 src/test/CompleteMerkle.t.sol delete mode 100644 src/test/OZMerkle.t.sol diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 49a2a7e..697dc6a 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -26,11 +26,17 @@ jobs: - name: Run Fuzzed Unit Tests run: forge test --no-match-path src/test/StandardInput.t.sol --fuzz-runs 10000 - - name: Run Differential Tests + - name: Run Murky Differential Tests run: | npm --prefix differential_testing/scripts/ install npm --prefix differential_testing/scripts/ run compile - forge test --ffi --contracts differential_testing/test/DifferentialTests.t.sol --fuzz-runs 512 + forge test --ffi --contracts differential_testing/test/DifferentialTests.t.sol --fuzz-runs 512 + + - name: Run Complete Differential Tests + run: | + npm --prefix differential_testing/scripts/ install + npm --prefix differential_testing/scripts/ run compile + forge test --ffi --contracts differential_testing/test/CompleteDifferentialTests.t.sol --fuzz-runs 512 - name: Run Standard Gas Snapshotting run: forge snapshot --gas-report --ffi --match-path src/test/StandardInput.t.sol \ No newline at end of file diff --git a/.gitignore b/.gitignore index 177604b..c6ed5c4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ out/ *.txt differential_testing/**/node_modules differential_testing/**/*.js +differential_testing/**/*.json differential_testing/data/input !remappings.txt \ No newline at end of file diff --git a/differential_testing/scripts/generate_complete_proof.ts b/differential_testing/scripts/generate_complete_proof.ts new file mode 100644 index 0000000..ced4e6a --- /dev/null +++ b/differential_testing/scripts/generate_complete_proof.ts @@ -0,0 +1,24 @@ +import { StandardMerkleTree } from "@openzeppelin/merkle-tree"; +import { ethers } from 'ethers'; + +const fs = require('fs'); +const input_file = process.argv[2]; +const input = JSON.parse(fs.readFileSync(input_file, 'utf8')); +const one_word = "0x0000000000000000000000000000000000000000000000000000000000000001" +const leafs = input['leafs'].map((bytes32) => [bytes32, one_word]); +const indexToProve = input['index']; +const tree = StandardMerkleTree.of(leafs, ["bytes32", "bytes32"], { sortLeaves: false }); // NO DEFAULT SORTING LEAVES +const proof = tree.getProof(indexToProve); +process.stdout.write(ethers.utils.defaultAbiCoder.encode(['bytes32[]'], [proof])); +// // const root = tree.root; +// // console.log(tree.entries()); +// for (const [i, v] of tree.entries()) { +// if (i == indexToProve) { +// const proof = tree.getProof(i); +// console.log('Value:', v); +// console.log('Proof:', proof); +// } +// } +// console.log(tree.root) +// console.log(tree.render()) + \ No newline at end of file diff --git a/differential_testing/scripts/generate_complete_root.ts b/differential_testing/scripts/generate_complete_root.ts new file mode 100644 index 0000000..0807149 --- /dev/null +++ b/differential_testing/scripts/generate_complete_root.ts @@ -0,0 +1,9 @@ +import { StandardMerkleTree } from "@openzeppelin/merkle-tree"; +const fs = require('fs'); +const input_file = process.argv[2]; +const input = JSON.parse(fs.readFileSync(input_file, 'utf8')); +const one_word = "0x0000000000000000000000000000000000000000000000000000000000000001" +const leafs = input['leafs'].map((bytes32) => [bytes32, one_word]); +const tree = StandardMerkleTree.of(leafs, ["bytes32", "bytes32"], { sortLeaves: false }); // NO DEFAULT SORTING LEAVES +process.stdout.write(tree.root); + diff --git a/differential_testing/scripts/package-lock.json b/differential_testing/scripts/package-lock.json index af2dd8d..a438fab 100644 --- a/differential_testing/scripts/package-lock.json +++ b/differential_testing/scripts/package-lock.json @@ -1,14 +1,38 @@ { - "name": "murky-uniswap", + "name": "murky-differential", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@ethersproject/abi": { + "packages": { + "": { + "name": "murky-differential", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@openzeppelin/merkle-tree": "^1.0.6", + "ethereumjs-util": "^7.1.4", + "ethers": "^5.6.4", + "rlp": "^3.0.0" + }, + "devDependencies": { + "typescript": "^4.6.3" + } + }, + "node_modules/@ethersproject/abi": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.1.tgz", "integrity": "sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w==", - "requires": { + "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.6.0", "@ethersproject/bignumber": "^5.6.0", "@ethersproject/bytes": "^5.6.0", @@ -20,11 +44,21 @@ "@ethersproject/strings": "^5.6.0" } }, - "@ethersproject/abstract-provider": { + "node_modules/@ethersproject/abstract-provider": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", - "requires": { + "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.6.0", "@ethersproject/bytes": "^5.6.0", "@ethersproject/logger": "^5.6.0", @@ -34,11 +68,21 @@ "@ethersproject/web": "^5.6.0" } }, - "@ethersproject/abstract-signer": { + "node_modules/@ethersproject/abstract-signer": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", - "requires": { + "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.6.0", "@ethersproject/bignumber": "^5.6.0", "@ethersproject/bytes": "^5.6.0", @@ -46,11 +90,21 @@ "@ethersproject/properties": "^5.6.0" } }, - "@ethersproject/address": { + "node_modules/@ethersproject/address": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", - "requires": { + "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.6.0", "@ethersproject/bytes": "^5.6.0", "@ethersproject/keccak256": "^5.6.0", @@ -58,61 +112,119 @@ "@ethersproject/rlp": "^5.6.0" } }, - "@ethersproject/base64": { + "node_modules/@ethersproject/base64": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", - "requires": { + "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.6.0" } }, - "@ethersproject/basex": { + "node_modules/@ethersproject/basex": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", - "requires": { + "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.6.0", "@ethersproject/properties": "^5.6.0" } }, - "@ethersproject/bignumber": { + "node_modules/@ethersproject/bignumber": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", - "requires": { + "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.6.0", "@ethersproject/logger": "^5.6.0", "bn.js": "^4.11.9" - }, - "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==" - } } }, - "@ethersproject/bytes": { + "node_modules/@ethersproject/bignumber/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==" + }, + "node_modules/@ethersproject/bytes": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", - "requires": { + "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.6.0" } }, - "@ethersproject/constants": { + "node_modules/@ethersproject/constants": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", - "requires": { + "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.6.0" } }, - "@ethersproject/contracts": { + "node_modules/@ethersproject/contracts": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.0.tgz", "integrity": "sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw==", - "requires": { + "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/abi": "^5.6.0", "@ethersproject/abstract-provider": "^5.6.0", "@ethersproject/abstract-signer": "^5.6.0", @@ -125,11 +237,21 @@ "@ethersproject/transactions": "^5.6.0" } }, - "@ethersproject/hash": { + "node_modules/@ethersproject/hash": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", - "requires": { + "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.6.0", "@ethersproject/address": "^5.6.0", "@ethersproject/bignumber": "^5.6.0", @@ -140,11 +262,21 @@ "@ethersproject/strings": "^5.6.0" } }, - "@ethersproject/hdnode": { + "node_modules/@ethersproject/hdnode": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.0.tgz", "integrity": "sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw==", - "requires": { + "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.6.0", "@ethersproject/basex": "^5.6.0", "@ethersproject/bignumber": "^5.6.0", @@ -159,11 +291,21 @@ "@ethersproject/wordlists": "^5.6.0" } }, - "@ethersproject/json-wallets": { + "node_modules/@ethersproject/json-wallets": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", - "requires": { + "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.6.0", "@ethersproject/address": "^5.6.0", "@ethersproject/bytes": "^5.6.0", @@ -179,50 +321,110 @@ "scrypt-js": "3.0.1" } }, - "@ethersproject/keccak256": { + "node_modules/@ethersproject/keccak256": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", - "requires": { + "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.6.0", "js-sha3": "0.8.0" } }, - "@ethersproject/logger": { + "node_modules/@ethersproject/logger": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] }, - "@ethersproject/networks": { + "node_modules/@ethersproject/networks": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.2.tgz", "integrity": "sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==", - "requires": { + "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.6.0" } }, - "@ethersproject/pbkdf2": { + "node_modules/@ethersproject/pbkdf2": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", - "requires": { + "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.6.0", "@ethersproject/sha2": "^5.6.0" } }, - "@ethersproject/properties": { + "node_modules/@ethersproject/properties": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", - "requires": { + "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.6.0" } }, - "@ethersproject/providers": { + "node_modules/@ethersproject/providers": { "version": "5.6.4", "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.4.tgz", "integrity": "sha512-WAdknnaZ52hpHV3qPiJmKx401BLpup47h36Axxgre9zT+doa/4GC/Ne48ICPxTm0BqndpToHjpLP1ZnaxyE+vw==", - "requires": { + "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.6.0", "@ethersproject/abstract-signer": "^5.6.0", "@ethersproject/address": "^5.6.0", @@ -244,59 +446,107 @@ "ws": "7.4.6" } }, - "@ethersproject/random": { + "node_modules/@ethersproject/random": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", - "requires": { + "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.6.0", "@ethersproject/logger": "^5.6.0" } }, - "@ethersproject/rlp": { + "node_modules/@ethersproject/rlp": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", - "requires": { + "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.6.0", "@ethersproject/logger": "^5.6.0" } }, - "@ethersproject/sha2": { + "node_modules/@ethersproject/sha2": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", - "requires": { + "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.6.0", "@ethersproject/logger": "^5.6.0", "hash.js": "1.1.7" } }, - "@ethersproject/signing-key": { + "node_modules/@ethersproject/signing-key": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", - "requires": { + "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.6.0", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", "bn.js": "^4.11.9", "elliptic": "6.5.4", "hash.js": "1.1.7" - }, - "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==" - } } }, - "@ethersproject/solidity": { + "node_modules/@ethersproject/signing-key/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==" + }, + "node_modules/@ethersproject/solidity": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", - "requires": { + "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.6.0", "@ethersproject/bytes": "^5.6.0", "@ethersproject/keccak256": "^5.6.0", @@ -305,21 +555,41 @@ "@ethersproject/strings": "^5.6.0" } }, - "@ethersproject/strings": { + "node_modules/@ethersproject/strings": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", - "requires": { + "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.6.0", "@ethersproject/constants": "^5.6.0", "@ethersproject/logger": "^5.6.0" } }, - "@ethersproject/transactions": { + "node_modules/@ethersproject/transactions": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", - "requires": { + "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.6.0", "@ethersproject/bignumber": "^5.6.0", "@ethersproject/bytes": "^5.6.0", @@ -331,21 +601,41 @@ "@ethersproject/signing-key": "^5.6.0" } }, - "@ethersproject/units": { + "node_modules/@ethersproject/units": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", - "requires": { + "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.6.0", "@ethersproject/constants": "^5.6.0", "@ethersproject/logger": "^5.6.0" } }, - "@ethersproject/wallet": { + "node_modules/@ethersproject/wallet": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.0.tgz", "integrity": "sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg==", - "requires": { + "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.6.0", "@ethersproject/abstract-signer": "^5.6.0", "@ethersproject/address": "^5.6.0", @@ -363,11 +653,21 @@ "@ethersproject/wordlists": "^5.6.0" } }, - "@ethersproject/web": { + "node_modules/@ethersproject/web": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", - "requires": { + "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.6.0", "@ethersproject/bytes": "^5.6.0", "@ethersproject/logger": "^5.6.0", @@ -375,11 +675,21 @@ "@ethersproject/strings": "^5.6.0" } }, - "@ethersproject/wordlists": { + "node_modules/@ethersproject/wordlists": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", - "requires": { + "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.6.0", "@ethersproject/hash": "^5.6.0", "@ethersproject/logger": "^5.6.0", @@ -387,73 +697,528 @@ "@ethersproject/strings": "^5.6.0" } }, - "@types/bn.js": { + "node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@openzeppelin/merkle-tree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/merkle-tree/-/merkle-tree-1.0.6.tgz", + "integrity": "sha512-cGWOb2WBWbJhqvupzxjnKAwGLxxAEYPg51sk76yZ5nVe5D03mw7Vx5yo8llaIEqYhP5O39M8QlrNWclgLfKVrA==", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "ethereum-cryptography": "^1.1.2" + } + }, + "node_modules/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/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==", + "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/@openzeppelin/merkle-tree/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/@scure/base": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", + "integrity": "sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@types/bn.js": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/node": { + "node_modules/@types/node": { "version": "17.0.25", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.25.tgz", "integrity": "sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w==" }, - "@types/pbkdf2": { + "node_modules/@types/pbkdf2": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/secp256k1": { + "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==", - "requires": { + "dependencies": { "@types/node": "*" } }, - "aes-js": { + "node_modules/aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" }, - "base-x": { + "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==", - "requires": { + "dependencies": { "safe-buffer": "^5.0.1" } }, - "bech32": { + "node_modules/bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, - "blakejs": { + "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==" }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "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==" }, - "brorand": { + "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, - "browserify-aes": { + "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==", - "requires": { + "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", "create-hash": "^1.1.0", @@ -462,43 +1227,43 @@ "safe-buffer": "^5.0.1" } }, - "bs58": { + "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { + "dependencies": { "base-x": "^3.0.2" } }, - "bs58check": { + "node_modules/bs58check": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { + "dependencies": { "bs58": "^4.0.0", "create-hash": "^1.1.0", "safe-buffer": "^5.1.2" } }, - "buffer-xor": { + "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, - "cipher-base": { + "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==", - "requires": { + "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" } }, - "create-hash": { + "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==", - "requires": { + "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", "md5.js": "^1.3.4", @@ -506,11 +1271,11 @@ "sha.js": "^2.4.0" } }, - "create-hmac": { + "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==", - "requires": { + "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", "inherits": "^2.0.1", @@ -519,11 +1284,11 @@ "sha.js": "^2.4.8" } }, - "elliptic": { + "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==", - "requires": { + "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", "hash.js": "^1.0.0", @@ -531,20 +1296,18 @@ "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==" - } } }, - "ethereum-cryptography": { + "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==" + }, + "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==", - "requires": { + "dependencies": { "@types/pbkdf2": "^3.0.0", "@types/secp256k1": "^4.0.1", "blakejs": "^1.1.0", @@ -562,33 +1325,47 @@ "setimmediate": "^1.0.5" } }, - "ethereumjs-util": { + "node_modules/ethereumjs-util": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", - "requires": { + "dependencies": { "@types/bn.js": "^5.1.0", "bn.js": "^5.1.2", "create-hash": "^1.1.2", "ethereum-cryptography": "^0.1.3", "rlp": "^2.2.4" }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/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==", "dependencies": { - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "requires": { - "bn.js": "^5.2.0" - } - } + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" } }, - "ethers": { + "node_modules/ethers": { "version": "5.6.4", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.4.tgz", "integrity": "sha512-62UIfxAQXdf67TeeOaoOoPctm5hUlYgfd0iW3wxfj7qRYKDcvvy0f+sJ3W2/Pyx77R8dblvejA8jokj+lS+ATQ==", - "requires": { + "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/abi": "5.6.1", "@ethersproject/abstract-provider": "5.6.0", "@ethersproject/abstract-signer": "5.6.0", @@ -621,195 +1398,259 @@ "@ethersproject/wordlists": "5.6.0" } }, - "evp_bytestokey": { + "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==", - "requires": { + "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" } }, - "hash-base": { + "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==", - "requires": { + "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" } }, - "hash.js": { + "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==", - "requires": { + "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" } }, - "hmac-drbg": { + "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { + "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "js-sha3": { + "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==" }, - "keccak": { + "node_modules/keccak": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "requires": { + "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" } }, - "md5.js": { + "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==", - "requires": { + "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, - "minimalistic-assert": { + "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==" }, - "minimalistic-crypto-utils": { + "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": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, - "node-addon-api": { + "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==" }, - "node-gyp-build": { + "node_modules/node-gyp-build": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } }, - "pbkdf2": { + "node_modules/pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { + "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" } }, - "randombytes": { + "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { + "dependencies": { "safe-buffer": "^5.1.0" } }, - "readable-stream": { + "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==", - "requires": { + "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "ripemd160": { + "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { + "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, - "rlp": { + "node_modules/rlp": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/rlp/-/rlp-3.0.0.tgz", - "integrity": "sha512-PD6U2PGk6Vq2spfgiWZdomLvRGDreBLxi5jv5M8EpRo3pU6VEm31KO+HFxE18Q3vgqfDrQ9pZA3FP95rkijNKw==" + "integrity": "sha512-PD6U2PGk6Vq2spfgiWZdomLvRGDreBLxi5jv5M8EpRo3pU6VEm31KO+HFxE18Q3vgqfDrQ9pZA3FP95rkijNKw==", + "bin": { + "rlp": "bin/rlp" + } }, - "safe-buffer": { + "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==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "scrypt-js": { + "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" }, - "secp256k1": { + "node_modules/secp256k1": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "requires": { + "hasInstallScript": true, + "dependencies": { "elliptic": "^6.5.4", "node-addon-api": "^2.0.0", "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "setimmediate": { + "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, - "sha.js": { + "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==", - "requires": { + "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" } }, - "string_decoder": { + "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==", - "requires": { + "dependencies": { "safe-buffer": "~5.2.0" } }, - "typescript": { + "node_modules/typescript": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "ws": { + "node_modules/ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "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 + } + } } } } diff --git a/differential_testing/scripts/package.json b/differential_testing/scripts/package.json index 8d664eb..fd371df 100644 --- a/differential_testing/scripts/package.json +++ b/differential_testing/scripts/package.json @@ -6,6 +6,7 @@ "author": "", "license": "MIT", "dependencies": { + "@openzeppelin/merkle-tree": "^1.0.6", "ethereumjs-util": "^7.1.4", "ethers": "^5.6.4", "rlp": "^3.0.0" @@ -14,9 +15,11 @@ "typescript": "^4.6.3" }, "scripts": { - "compile": "npx tsc --esModuleInterop ./*.ts", + "compile": "npx tsc --esModuleInterop --downlevelIteration ./*.ts", "generate-root": "node generate_root.js", "generate-root-129": "node generate_root.js", - "generate-root-cli": "node generate_root_cli.js" + "generate-root-cli": "node generate_root_cli.js", + "generate-complete-root": "node generate_complete_root.js", + "generate-complete-proof": "node generate_complete_proof.js" } } diff --git a/differential_testing/test/CompleteDifferentialTests.t.sol b/differential_testing/test/CompleteDifferentialTests.t.sol new file mode 100644 index 0000000..307396d --- /dev/null +++ b/differential_testing/test/CompleteDifferentialTests.t.sol @@ -0,0 +1,87 @@ +pragma solidity ^0.8.4; + +import "../../src/CompleteMerkle.sol"; +import "forge-std/Test.sol"; +import "./utils/Strings2.sol"; + + +contract CompleteDifferentialTests is Test { + CompleteMerkle m; + bytes32 oneword; + using {Strings2.toHexString} for bytes; + + + function setUp() public { + m = new CompleteMerkle(); + oneword = bytes32(uint256(0x1)); + } + + function testDifferentialOZMerkleTreeRootGeneration(bytes32[] memory leafs) public { + // Setup assumptions + vm.assume(leafs.length > 1); + + // Generate the input json to be used by the JS implementation + string memory obj1 = vm.serializeBytes32("input", "leafs", leafs); + vm.writeJson(obj1, "./differential_testing/test/diff_input.json"); + + // Prepare the leafs. OZ JS Merkle double hashes and expects each leaf to be a len(2) array (e.g. address, amount) + // For this test we use the fuzzed bytes32 and a constant bytes32 0x1 + bytes32[] memory compatibleLeafs = new bytes32[](leafs.length); + for (uint256 i = 0; i < leafs.length; ++i) { + compatibleLeafs[i] = keccak256(abi.encode(keccak256(abi.encode(leafs[i],oneword)))); + } + + // Run ffi and read back the oz generated root + string[] memory runJsInputs = new string[](7); + runJsInputs[0] = 'npm'; + runJsInputs[1] = '--prefix'; + runJsInputs[2] = 'differential_testing/scripts/'; + runJsInputs[3] = '--silent'; + runJsInputs[4] = 'run'; + runJsInputs[5] = 'generate-complete-root'; // Generates length 129 by default + runJsInputs[6] = "../test/diff_input.json"; + bytes memory jsResult = vm.ffi(runJsInputs); + bytes32 ozGeneratedRoot = abi.decode(jsResult, (bytes32)); + + // generate our root and compare + bytes32 root = m.getRoot(compatibleLeafs); + assertEq(root, ozGeneratedRoot); + } + + function testDifferentialOZMerkleTreeProofGeneration(bytes32[] memory leafs, uint256 index) public { + // Setup assumptions + vm.assume(leafs.length > 1); + vm.assume(index < leafs.length); + + string memory obj1 = "input"; + vm.serializeBytes32(obj1, "leafs", leafs); + string memory obj2 = vm.serializeUint(obj1, "index", index); + vm.writeJson(obj2, "./differential_testing/test/proof_input.json"); + + // Prepare the leafs. OZ JS Merkle double hashes and expects each leaf to be a len(2) array (e.g. address, amount) + // For this test we use the fuzzed bytes32 and a constant bytes32 0x1 + bytes32[] memory compatibleLeafs = new bytes32[](leafs.length); + for (uint256 i = 0; i < leafs.length; ++i) { + compatibleLeafs[i] = keccak256(abi.encode(keccak256(abi.encode(leafs[i],oneword)))); + } + + bytes32[] memory proof = m.getProof(compatibleLeafs, index); + // Run ffi and read back the oz generated root + string[] memory runJsInputs = new string[](7); + runJsInputs[0] = 'npm'; + runJsInputs[1] = '--prefix'; + runJsInputs[2] = 'differential_testing/scripts/'; + runJsInputs[3] = '--silent'; + runJsInputs[4] = 'run'; + runJsInputs[5] = 'generate-complete-proof'; + runJsInputs[6] = "../test/proof_input.json"; + bytes memory jsResult = vm.ffi(runJsInputs); + bytes32[] memory ozGeneratedProof = abi.decode(jsResult, (bytes32[])); + + // assert proofs are equal + assertEq(proof.length, ozGeneratedProof.length); + for (uint256 i = 0; i < proof.length; ++i) { + assertEq(proof[i], ozGeneratedProof[i]); + } + } +} diff --git a/src/CompleteMerkle.sol b/src/CompleteMerkle.sol index 8d02460..282d7cb 100644 --- a/src/CompleteMerkle.sol +++ b/src/CompleteMerkle.sol @@ -63,8 +63,7 @@ contract CompleteMerkle { // TODO: clean all this up, mainly broken out for early understanding and debugging let left := mload(add(tree, mul(sub(i, 1), 0x20))) let right := mload(add(tree, mul(i, 0x20))) - let indexToWrite := div(sub(i, 1), 2) - let posToWrite := add(tree, mul(indexToWrite, 0x20)) + let posToWrite := add(tree, shr(1, mul(sub(i, 1), 0x20))) mstore(posToWrite, hash_leafs(left, right)) } } diff --git a/src/test/CompleteMerkle.t.sol b/src/test/CompleteMerkle.t.sol new file mode 100644 index 0000000..27bccad --- /dev/null +++ b/src/test/CompleteMerkle.t.sol @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +import "../Merkle.sol"; +import "../CompleteMerkle.sol"; +import "forge-std/Test.sol"; +import "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol"; +import "openzeppelin-contracts/contracts/utils/Strings.sol"; +import "forge-std/console.sol"; + +contract CompleteMerkleTest is Test { + Merkle m; + CompleteMerkle cm; + + function setUp() public { + m = new Merkle(); + cm = new CompleteMerkle(); + } + + function testGenerateProof(bytes32[] memory data, uint256 node) public { + vm.assume(data.length > 1); + vm.assume(node < data.length); + bytes32 root = m.getRoot(data); + bytes32[] memory proof = m.getProof(data, node); + bytes32 valueToProve = data[node]; + + bytes32 rollingHash = valueToProve; + for (uint256 i = 0; i < proof.length; ++i) { + rollingHash = m.hashLeafPairs(rollingHash, proof[i]); + } + assertEq(rollingHash, root); + } + + function testVerifyProof(bytes32[] memory data, uint256 node) public { + vm.assume(data.length > 1); + vm.assume(node < data.length); + bytes32 root = m.getRoot(data); + bytes32[] memory proof = m.getProof(data, node); + bytes32 valueToProve = data[node]; + assertTrue(m.verifyProof(root, proof, valueToProve)); + } + + function testFailVerifyProof(bytes32[] memory data, bytes32 valueToProve, uint256 node) public { + vm.assume(data.length > 1); + vm.assume(node < data.length); + vm.assume(valueNotInArray(data, valueToProve)); + bytes32 root = m.getRoot(data); + bytes32[] memory proof = m.getProof(data, node); + assertTrue(m.verifyProof(root, proof, valueToProve)); + } + + // function testVerifyProofOzForGasComparison(bytes32[] memory data, uint256 node) public { + // vm.assume(data.length > 1); + // vm.assume(node < data.length); + // bytes32 root = m.getRoot(data); + // bytes32[] memory proof = m.getProof(data, node); + // bytes32 valueToProve = data[node]; + // assertTrue(MerkleProof.verify(proof, root, valueToProve)); + // } + + function testWontGetRootSingleLeaf() public { + bytes32[] memory data = new bytes32[](1); + data[0] = bytes32(0x0); + vm.expectRevert("won't generate root for single leaf"); + m.getRoot(data); + } + + function testWontGetProofSingleLeaf() public { + bytes32[] memory data = new bytes32[](1); + data[0] = bytes32(0x0); + vm.expectRevert("won't generate proof for single leaf"); + m.getProof(data, 0x0); + } + + function valueNotInArray(bytes32[] memory data, bytes32 value) public pure returns (bool) { + for (uint256 i = 0; i < data.length; ++i) { + if (data[i] == value) return false; + } + return true; + } + + function testRootGenerationBasicExampleLen6() public { + bytes32[] memory data = new bytes32[](6); + + data[0] = 0xcf0e8c2fa63ea2b3726dbea696df21baec00c4cdb37deeab03a15f190659544c; // sha3(alice, address(0x0)) + data[1] = 0xafeb0ccce3b008968e7ffbfc7482d85551f5f90e713b8441449d808d25e9cc64; // sha3(bob, address(0x0)) + data[2] = 0x7f37e8358c0d3959e3e800344c357551753c24a55d5d987cef461e933b137a02; // sha3(charlie, address(0x0)) + data[3] = 0xde1820ee7887b5ae922f14f423bb2e7a6595e423f1a0c0a82a2ddeed09a92a25; + data[4] = 0xcac6fc160d04af9e1fd8f0c71cf8d333453b39589d3846524462ee7737bd728d; + data[5] = 0x1688f29243f54ddded6dedcbbc8dae64ef939f0b967d0fa56a6e5938febb5f79; + //bytes32[] memory tree = cm._getTree(data); + bytes32 root = cm.getRoot(data); + assertEq(root, root); + } + + function testRootGenerationRegularMerkle6ForGas() public { + bytes32[] memory data = new bytes32[](6); + + data[0] = 0xcf0e8c2fa63ea2b3726dbea696df21baec00c4cdb37deeab03a15f190659544c; // sha3(alice, address(0x0)) + data[1] = 0xafeb0ccce3b008968e7ffbfc7482d85551f5f90e713b8441449d808d25e9cc64; // sha3(bob, address(0x0)) + data[2] = 0x7f37e8358c0d3959e3e800344c357551753c24a55d5d987cef461e933b137a02; // sha3(charlie, address(0x0)) + data[3] = 0xde1820ee7887b5ae922f14f423bb2e7a6595e423f1a0c0a82a2ddeed09a92a25; + data[4] = 0xcac6fc160d04af9e1fd8f0c71cf8d333453b39589d3846524462ee7737bd728d; + data[5] = 0x1688f29243f54ddded6dedcbbc8dae64ef939f0b967d0fa56a6e5938febb5f79; + //bytes32[] memory tree = cm._getTree(data); + bytes32 root = m.getRoot(data); + assertEq(root, root); + } +} diff --git a/src/test/OZMerkle.t.sol b/src/test/OZMerkle.t.sol deleted file mode 100644 index e9a5131..0000000 --- a/src/test/OZMerkle.t.sol +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.4; - -import "../Merkle.sol"; -import "../CompleteMerkle.sol"; -import "forge-std/Test.sol"; -import "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol"; -import "openzeppelin-contracts/contracts/utils/Strings.sol"; -import "forge-std/console.sol"; - -contract ContractTest is Test { - Merkle m; - CompleteMerkle cm; - - function setUp() public { - m = new Merkle(); - cm = new CompleteMerkle(); - } - - // function testHashes(bytes32 left, bytes32 right) public { - // bytes32 hAssem = m.hashLeafPairs(left, right); - // bytes memory packed; - // if (left <= right) { - // packed = abi.encodePacked(left, right); - // } else { - // if (right == bytes32(0x0)) { - // packed = abi.encodePacked(left, left); - // } else { - // packed = abi.encodePacked(right, left); - // } - // } - // bytes32 hNaive = keccak256(packed); - // assertEq(hAssem, hNaive); - // } - - // function testHashesDuplicateOddLeaf(bytes32 left) public { - // bytes32 right = bytes32(0x0); - // bytes32 hAssem = m.hashLeafPairs(left, right); - // bytes memory packed = abi.encodePacked(left, left); - // bytes32 hNaive = keccak256(packed); - // assertEq(hAssem, hNaive); - // } - - // function testGenerateProof(bytes32[] memory data, uint256 node) public { - // vm.assume(data.length > 1); - // vm.assume(node < data.length); - // bytes32 root = m.getRoot(data); - // bytes32[] memory proof = m.getProof(data, node); - // bytes32 valueToProve = data[node]; - - // bytes32 rollingHash = valueToProve; - // for (uint256 i = 0; i < proof.length; ++i) { - - // rollingHash = m.hashLeafPairs(rollingHash, proof[i]); - // } - // assertEq(rollingHash, root); - // } - - // function testVerifyProof(bytes32[] memory data, uint256 node) public { - // vm.assume(data.length > 1); - // vm.assume(node < data.length); - // bytes32 root = m.getRoot(data); - // bytes32[] memory proof = m.getProof(data, node); - // bytes32 valueToProve = data[node]; - // assertTrue(m.verifyProof(root, proof, valueToProve)); - // } - - // function testFailVerifyProof(bytes32[] memory data, bytes32 valueToProve, uint256 node) public { - // vm.assume(data.length > 1); - // vm.assume(node < data.length); - // vm.assume(valueNotInArray(data, valueToProve)); - // bytes32 root = m.getRoot(data); - // bytes32[] memory proof = m.getProof(data, node); - // assertTrue(m.verifyProof(root, proof, valueToProve)); - // } - - // // function testVerifyProofOzForGasComparison(bytes32[] memory data, uint256 node) public { - // // vm.assume(data.length > 1); - // // vm.assume(node < data.length); - // // bytes32 root = m.getRoot(data); - // // bytes32[] memory proof = m.getProof(data, node); - // // bytes32 valueToProve = data[node]; - // // assertTrue(MerkleProof.verify(proof, root, valueToProve)); - // // } - - // function testWontGetRootSingleLeaf() public { - // bytes32[] memory data = new bytes32[](1); - // data[0] = bytes32(0x0); - // vm.expectRevert("won't generate root for single leaf"); - // m.getRoot(data); - // } - - // function testWontGetProofSingleLeaf() public { - // bytes32[] memory data = new bytes32[](1); - // data[0] = bytes32(0x0); - // vm.expectRevert("won't generate proof for single leaf"); - // m.getProof(data, 0x0); - // } - - // function valueNotInArray(bytes32[] memory data, bytes32 value) public pure returns (bool) { - // for (uint256 i = 0; i < data.length; ++i) { - // if (data[i] == value) return false; - // } - // return true; - // } - - function testRootGenerationBasicExampleLen3() public { - bytes32[] memory data = new bytes32[](3); - data[0] = 0xcf0e8c2fa63ea2b3726dbea696df21baec00c4cdb37deeab03a15f190659544c; // sha3(alice, address(0x0)) - data[1] = 0xafeb0ccce3b008968e7ffbfc7482d85551f5f90e713b8441449d808d25e9cc64; // sha3(bob, address(0x0)) - data[2] = 0x7f37e8358c0d3959e3e800344c357551753c24a55d5d987cef461e933b137a02; // sha3(charlie, address(0x0)) - //bytes32[] memory tree = cm._getTree(data); - bytes32 root = cm.getRoot(data); - assertEq(root, bytes32(0x10d772be44576d1c88a8039062ea3cd6163862f2deca298213e35b18cbd85490)); - } - - function testRootGenerationBasicExampleLen5() public { - bytes32[] memory data = new bytes32[](5); - - data[0] = 0xcf0e8c2fa63ea2b3726dbea696df21baec00c4cdb37deeab03a15f190659544c; // sha3(alice, address(0x0)) - data[1] = 0xafeb0ccce3b008968e7ffbfc7482d85551f5f90e713b8441449d808d25e9cc64; // sha3(bob, address(0x0)) - data[2] = 0x7f37e8358c0d3959e3e800344c357551753c24a55d5d987cef461e933b137a02; // sha3(charlie, address(0x0)) - data[3] = 0xde1820ee7887b5ae922f14f423bb2e7a6595e423f1a0c0a82a2ddeed09a92a25; - data[4] = 0xcac6fc160d04af9e1fd8f0c71cf8d333453b39589d3846524462ee7737bd728d; - bytes32 elem; - // assembly { - // elem := mload(data) - // } - // emit log_bytes32((elem)); - // bytes32[] memory tree = cm._getTree(data); - // for (uint256 i = 0; i < tree.length; ++i) { - // emit log_bytes32(tree[i]); - // } - bytes32 root = cm.getRoot(data); - assertEq(root, bytes32(0xe0c1356e7bc3ae6e7a3f1d1db657fdd88f043cf540e8ef3ca1a7f22fac936703)); - } - - function testRootGenerationBasicExampleLen6() public { - bytes32[] memory data = new bytes32[](6); - - data[0] = 0xcf0e8c2fa63ea2b3726dbea696df21baec00c4cdb37deeab03a15f190659544c; // sha3(alice, address(0x0)) - data[1] = 0xafeb0ccce3b008968e7ffbfc7482d85551f5f90e713b8441449d808d25e9cc64; // sha3(bob, address(0x0)) - data[2] = 0x7f37e8358c0d3959e3e800344c357551753c24a55d5d987cef461e933b137a02; // sha3(charlie, address(0x0)) - data[3] = 0xde1820ee7887b5ae922f14f423bb2e7a6595e423f1a0c0a82a2ddeed09a92a25; - data[4] = 0xcac6fc160d04af9e1fd8f0c71cf8d333453b39589d3846524462ee7737bd728d; - data[5] = 0x1688f29243f54ddded6dedcbbc8dae64ef939f0b967d0fa56a6e5938febb5f79; - //bytes32[] memory tree = cm._getTree(data); - bytes32 root = cm.getRoot(data); - assertEq(root, bytes32(0x82e830e6e22a0b487eac4fc6868317898b8c2131d21821dd2c8d723306afeb0a)); - - } - - function testRootGenerationRegularMerkle6ForGas() public { - bytes32[] memory data = new bytes32[](6); - - data[0] = 0xcf0e8c2fa63ea2b3726dbea696df21baec00c4cdb37deeab03a15f190659544c; // sha3(alice, address(0x0)) - data[1] = 0xafeb0ccce3b008968e7ffbfc7482d85551f5f90e713b8441449d808d25e9cc64; // sha3(bob, address(0x0)) - data[2] = 0x7f37e8358c0d3959e3e800344c357551753c24a55d5d987cef461e933b137a02; // sha3(charlie, address(0x0)) - data[3] = 0xde1820ee7887b5ae922f14f423bb2e7a6595e423f1a0c0a82a2ddeed09a92a25; - data[4] = 0xcac6fc160d04af9e1fd8f0c71cf8d333453b39589d3846524462ee7737bd728d; - data[5] = 0x1688f29243f54ddded6dedcbbc8dae64ef939f0b967d0fa56a6e5938febb5f79; - //bytes32[] memory tree = cm._getTree(data); - bytes32 root = m.getRoot(data); - assertEq(true, true); - - } -}