diff --git a/cli.js b/cli.js index 9c5eab1..bab65a2 100755 --- a/cli.js +++ b/cli.js @@ -10,7 +10,7 @@ const snarkjs = require('snarkjs') const crypto = require('crypto') const circomlib = require('circomlib') const bigInt = snarkjs.bigInt -const merkleTree = require('./lib/MerkleTree') +const merkleTree = require('fixed-merkle-tree') const Web3 = require('web3') const buildGroth16 = require('websnark/src/groth16') const websnarkUtils = require('websnark/src/utils') @@ -126,7 +126,7 @@ async function generateMerkleProof(deposit) { const leafIndex = depositEvent ? depositEvent.returnValues.leafIndex : -1 // Validate that our data is correct - const root = await tree.root() + const root = tree.root() const isValidRoot = await tornado.methods.isKnownRoot(toHex(root)).call() const isSpent = await tornado.methods.isSpent(toHex(deposit.nullifierHash)).call() assert(isValidRoot === true, 'Merkle tree is corrupted') @@ -147,7 +147,7 @@ async function generateMerkleProof(deposit) { */ async function generateProof({ deposit, recipient, relayerAddress = 0, fee = 0, refund = 0 }) { // Compute merkle proof of our commitment - const { root, path_elements, path_index } = await generateMerkleProof(deposit) + const { root, pathElements, pathIndices } = await generateMerkleProof(deposit) // Prepare circuit input const input = { @@ -162,8 +162,8 @@ async function generateProof({ deposit, recipient, relayerAddress = 0, fee = 0, // Private snark inputs nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, } console.log('Generating SNARK proof') diff --git a/lib/MerkleTree.js b/lib/MerkleTree.js deleted file mode 100644 index 312fb97..0000000 --- a/lib/MerkleTree.js +++ /dev/null @@ -1,186 +0,0 @@ -const jsStorage = require('./Storage') -const hasherImpl = require('./MiMC') - -class MerkleTree { - constructor(n_levels, defaultElements, prefix, storage, hasher) { - this.prefix = prefix - this.storage = storage || new jsStorage() - this.hasher = hasher || new hasherImpl() - this.n_levels = n_levels - this.zero_values = [] - this.totalElements = 0 - - let current_zero_value = '21663839004416932945382355908790599225266501822907911457504978515578255421292' - this.zero_values.push(current_zero_value) - for (let i = 0; i < n_levels; i++) { - current_zero_value = this.hasher.hash(i, current_zero_value, current_zero_value) - this.zero_values.push(current_zero_value.toString()) - } - if (defaultElements) { - let level = 0 - this.totalElements = defaultElements.length - defaultElements.forEach((element, i) => { - this.storage.put(MerkleTree.index_to_key(prefix, level, i), element) - }) - level++ - let numberOfElementsInLevel = Math.ceil(defaultElements.length / 2) - for (level; level <= this.n_levels; level++) { - for (let i = 0; i < numberOfElementsInLevel; i++) { - const leftKey = MerkleTree.index_to_key(prefix, level - 1, 2 * i) - const rightKey = MerkleTree.index_to_key(prefix, level - 1, 2 * i + 1) - - const left = this.storage.get(leftKey) - const right = this.storage.get_or_element(rightKey, this.zero_values[level - 1]) - - const subRoot = this.hasher.hash(null, left, right) - this.storage.put(MerkleTree.index_to_key(prefix, level, i), subRoot) - } - numberOfElementsInLevel = Math.ceil(numberOfElementsInLevel / 2) - } - } - } - - static index_to_key(prefix, level, index) { - const key = `${prefix}_tree_${level}_${index}` - return key - } - - async root() { - let root = await this.storage.get_or_element( - MerkleTree.index_to_key(this.prefix, this.n_levels, 0), - this.zero_values[this.n_levels], - ) - - return root - } - - async path(index) { - class PathTraverser { - constructor(prefix, storage, zero_values) { - this.prefix = prefix - this.storage = storage - this.zero_values = zero_values - this.path_elements = [] - this.path_index = [] - } - - async handle_index(level, element_index, sibling_index) { - const sibling = await this.storage.get_or_element( - MerkleTree.index_to_key(this.prefix, level, sibling_index), - this.zero_values[level], - ) - this.path_elements.push(sibling) - this.path_index.push(element_index % 2) - } - } - index = Number(index) - let traverser = new PathTraverser(this.prefix, this.storage, this.zero_values) - const root = await this.storage.get_or_element( - MerkleTree.index_to_key(this.prefix, this.n_levels, 0), - this.zero_values[this.n_levels], - ) - - const element = await this.storage.get_or_element( - MerkleTree.index_to_key(this.prefix, 0, index), - this.zero_values[0], - ) - - await this.traverse(index, traverser) - return { - root, - path_elements: traverser.path_elements, - path_index: traverser.path_index, - element, - } - } - - async update(index, element, insert = false) { - if (!insert && index >= this.totalElements) { - throw Error('Use insert method for new elements.') - } else if (insert && index < this.totalElements) { - throw Error('Use update method for existing elements.') - } - try { - class UpdateTraverser { - constructor(prefix, storage, hasher, element, zero_values) { - this.prefix = prefix - this.current_element = element - this.zero_values = zero_values - this.storage = storage - this.hasher = hasher - this.key_values_to_put = [] - } - - async handle_index(level, element_index, sibling_index) { - if (level == 0) { - this.original_element = await this.storage.get_or_element( - MerkleTree.index_to_key(this.prefix, level, element_index), - this.zero_values[level], - ) - } - const sibling = await this.storage.get_or_element( - MerkleTree.index_to_key(this.prefix, level, sibling_index), - this.zero_values[level], - ) - let left, right - if (element_index % 2 == 0) { - left = this.current_element - right = sibling - } else { - left = sibling - right = this.current_element - } - - this.key_values_to_put.push({ - key: MerkleTree.index_to_key(this.prefix, level, element_index), - value: this.current_element, - }) - this.current_element = this.hasher.hash(level, left, right) - } - } - let traverser = new UpdateTraverser(this.prefix, this.storage, this.hasher, element, this.zero_values) - - await this.traverse(index, traverser) - traverser.key_values_to_put.push({ - key: MerkleTree.index_to_key(this.prefix, this.n_levels, 0), - value: traverser.current_element, - }) - - await this.storage.put_batch(traverser.key_values_to_put) - } catch (e) { - console.error(e) - } - } - - async insert(element) { - const index = this.totalElements - await this.update(index, element, true) - this.totalElements++ - } - - async traverse(index, handler) { - let current_index = index - for (let i = 0; i < this.n_levels; i++) { - let sibling_index = current_index - if (current_index % 2 == 0) { - sibling_index += 1 - } else { - sibling_index -= 1 - } - await handler.handle_index(i, current_index, sibling_index) - current_index = Math.floor(current_index / 2) - } - } - - getIndexByElement(element) { - for (let i = this.totalElements - 1; i >= 0; i--) { - const elementFromTree = this.storage.get(MerkleTree.index_to_key(this.prefix, 0, i)) - if (elementFromTree === element) { - return i - } - } - return false - } -} - -module.exports = MerkleTree diff --git a/lib/MiMC.js b/lib/MiMC.js deleted file mode 100644 index d070373..0000000 --- a/lib/MiMC.js +++ /dev/null @@ -1,13 +0,0 @@ -const circomlib = require('circomlib') -const mimcsponge = circomlib.mimcsponge -const snarkjs = require('snarkjs') - -const bigInt = snarkjs.bigInt - -class MimcSpongeHasher { - hash(level, left, right) { - return mimcsponge.multiHash([bigInt(left), bigInt(right)]).toString() - } -} - -module.exports = MimcSpongeHasher diff --git a/lib/Storage.js b/lib/Storage.js deleted file mode 100644 index e6b1e93..0000000 --- a/lib/Storage.js +++ /dev/null @@ -1,37 +0,0 @@ -class JsStorage { - constructor() { - this.db = {} - } - - get(key) { - return this.db[key] - } - - get_or_element(key, defaultElement) { - const element = this.db[key] - if (element === undefined) { - return defaultElement - } else { - return element - } - } - - put(key, value) { - if (key === undefined || value === undefined) { - throw Error('key or value is undefined') - } - this.db[key] = value - } - - del(key) { - delete this.db[key] - } - - put_batch(key_values) { - key_values.forEach((element) => { - this.db[element.key] = element.value - }) - } -} - -module.exports = JsStorage diff --git a/minimal-demo.js b/minimal-demo.js index 70612c0..47eb31b 100644 --- a/minimal-demo.js +++ b/minimal-demo.js @@ -3,7 +3,7 @@ const assert = require('assert') const { bigInt } = require('snarkjs') const crypto = require('crypto') const circomlib = require('circomlib') -const merkleTree = require('./lib/MerkleTree') +const merkleTree = require('fixed-merkle-tree') const Web3 = require('web3') const buildGroth16 = require('websnark/src/groth16') const websnarkUtils = require('websnark/src/utils') @@ -99,14 +99,14 @@ async function generateMerkleProof(deposit) { let leafIndex = depositEvent ? depositEvent.returnValues.leafIndex : -1 // Validate that our data is correct (optional) - const isValidRoot = await contract.methods.isKnownRoot(toHex(await tree.root())).call() + const isValidRoot = await contract.methods.isKnownRoot(toHex(tree.root())).call() const isSpent = await contract.methods.isSpent(toHex(deposit.nullifierHash)).call() assert(isValidRoot === true, 'Merkle tree is corrupted') assert(isSpent === false, 'The note is already spent') assert(leafIndex >= 0, 'The deposit is not found in the tree') // Compute merkle proof of our commitment - return await tree.path(leafIndex) + return tree.path(leafIndex) } /** @@ -116,7 +116,7 @@ async function generateMerkleProof(deposit) { */ async function generateSnarkProof(deposit, recipient) { // Compute merkle proof of our commitment - const { root, path_elements, path_index } = await generateMerkleProof(deposit) + const { root, pathElements, pathIndices } = generateMerkleProof(deposit) // Prepare circuit input const input = { @@ -131,8 +131,8 @@ async function generateSnarkProof(deposit, recipient) { // Private snark inputs nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, } console.log('Generating SNARK proof...') diff --git a/package.json b/package.json index 9deb37f..bf370eb 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "eslint-config-prettier": "^7.2.0", "eslint-plugin-prettier": "^3.3.1", "eth-json-rpc-filters": "^4.1.1", + "fixed-merkle-tree": "^0.6.0", "ganache-cli": "^6.7.0", "prettier": "^2.2.1", "prettier-plugin-solidity": "^1.0.0-beta.3", diff --git a/test/ERC20Tornado.test.js b/test/ERC20Tornado.test.js index a0d3e67..a4b4680 100644 --- a/test/ERC20Tornado.test.js +++ b/test/ERC20Tornado.test.js @@ -18,7 +18,7 @@ const snarkjs = require('snarkjs') const bigInt = snarkjs.bigInt const crypto = require('crypto') const circomlib = require('circomlib') -const MerkleTree = require('../lib/MerkleTree') +const MerkleTree = require('fixed-merkle-tree') const rbigint = (nbytes) => snarkjs.bigInt.leBuff2int(crypto.randomBytes(nbytes)) const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0] @@ -49,7 +49,6 @@ contract('ERC20Tornado', (accounts) => { const levels = MERKLE_TREE_HEIGHT || 16 let tokenDenomination = TOKEN_AMOUNT || '1000000000000000000' // 1 ether let snapshotId - let prefix = 'test' let tree const fee = bigInt(ETH_AMOUNT).shr(1) || bigInt(1e17) const refund = ETH_AMOUNT || '1000000000000000000' // 1 ether @@ -60,7 +59,7 @@ contract('ERC20Tornado', (accounts) => { let proving_key before(async () => { - tree = new MerkleTree(levels, null, prefix) + tree = new MerkleTree(levels) tornado = await Tornado.deployed() if (ERC20_TOKEN) { token = await Token.at(ERC20_TOKEN) @@ -108,7 +107,7 @@ contract('ERC20Tornado', (accounts) => { it('should work', async () => { const deposit = generateDeposit() const user = accounts[4] - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await token.mint(user, tokenDenomination) const balanceUserBefore = await token.balanceOf(user) @@ -121,11 +120,11 @@ contract('ERC20Tornado', (accounts) => { const balanceUserAfter = await token.balanceOf(user) balanceUserAfter.should.be.eq.BN(toBN(balanceUserBefore).sub(toBN(tokenDenomination))) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) // Circuit input const input = stringifyBigInts({ // public - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), relayer, recipient, @@ -135,8 +134,8 @@ contract('ERC20Tornado', (accounts) => { // private nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -193,7 +192,7 @@ contract('ERC20Tornado', (accounts) => { const deposit = generateDeposit() const user = accounts[4] recipient = bigInt(badRecipient.address) - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await token.mint(user, tokenDenomination) const balanceUserBefore = await token.balanceOf(user) @@ -203,11 +202,11 @@ contract('ERC20Tornado', (accounts) => { const balanceUserAfter = await token.balanceOf(user) balanceUserAfter.should.be.eq.BN(toBN(balanceUserBefore).sub(toBN(tokenDenomination))) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) // Circuit input const input = stringifyBigInts({ // public - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), relayer, recipient, @@ -217,8 +216,8 @@ contract('ERC20Tornado', (accounts) => { // private nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -272,16 +271,16 @@ contract('ERC20Tornado', (accounts) => { it('should reject with wrong refund value', async () => { const deposit = generateDeposit() const user = accounts[4] - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await token.mint(user, tokenDenomination) await token.approve(tornado.address, tokenDenomination, { from: user }) await tornado.deposit(toFixedHex(deposit.commitment), { from: user, gasPrice: '0' }) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) // Circuit input const input = stringifyBigInts({ // public - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), relayer, recipient, @@ -291,8 +290,8 @@ contract('ERC20Tornado', (accounts) => { // private nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -329,7 +328,7 @@ contract('ERC20Tornado', (accounts) => { console.log('userBal', userBal.toString()) const senderBal = await usdtToken.balanceOf(sender) console.log('senderBal', senderBal.toString()) - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await usdtToken.transfer(user, tokenDenomination, { from: sender }) console.log('transfer done') @@ -345,12 +344,12 @@ contract('ERC20Tornado', (accounts) => { const balanceUserAfter = await usdtToken.balanceOf(user) balanceUserAfter.should.be.eq.BN(toBN(balanceUserBefore).sub(toBN(tokenDenomination))) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) // Circuit input const input = stringifyBigInts({ // public - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), relayer: operator, recipient, @@ -360,8 +359,8 @@ contract('ERC20Tornado', (accounts) => { // private nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -418,7 +417,7 @@ contract('ERC20Tornado', (accounts) => { console.log('userBal', userBal.toString()) const senderBal = await token.balanceOf(sender) console.log('senderBal', senderBal.toString()) - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await token.transfer(user, tokenDenomination, { from: sender }) console.log('transfer done') @@ -432,12 +431,12 @@ contract('ERC20Tornado', (accounts) => { const balanceUserAfter = await token.balanceOf(user) balanceUserAfter.should.be.eq.BN(toBN(balanceUserBefore).sub(toBN(tokenDenomination))) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) // Circuit input const input = stringifyBigInts({ // public - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), relayer: operator, recipient, @@ -447,8 +446,8 @@ contract('ERC20Tornado', (accounts) => { // private nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -501,6 +500,6 @@ contract('ERC20Tornado', (accounts) => { await revertSnapshot(snapshotId.result) // eslint-disable-next-line require-atomic-updates snapshotId = await takeSnapshot() - tree = new MerkleTree(levels, null, prefix) + tree = new MerkleTree(levels) }) }) diff --git a/test/ETHTornado.test.js b/test/ETHTornado.test.js index 39fd454..b8a5656 100644 --- a/test/ETHTornado.test.js +++ b/test/ETHTornado.test.js @@ -16,7 +16,7 @@ const snarkjs = require('snarkjs') const bigInt = snarkjs.bigInt const crypto = require('crypto') const circomlib = require('circomlib') -const MerkleTree = require('../lib/MerkleTree') +const MerkleTree = require('fixed-merkle-tree') const rbigint = (nbytes) => snarkjs.bigInt.leBuff2int(crypto.randomBytes(nbytes)) const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0] @@ -59,7 +59,6 @@ contract('ETHTornado', (accounts) => { const levels = MERKLE_TREE_HEIGHT || 16 const value = ETH_AMOUNT || '1000000000000000000' // 1 ether let snapshotId - let prefix = 'test' let tree const fee = bigInt(ETH_AMOUNT).shr(1) || bigInt(1e17) const refund = bigInt(0) @@ -70,7 +69,7 @@ contract('ETHTornado', (accounts) => { let proving_key before(async () => { - tree = new MerkleTree(levels, null, prefix) + tree = new MerkleTree(levels) tornado = await Tornado.deployed() snapshotId = await takeSnapshot() groth16 = await buildGroth16() @@ -113,11 +112,11 @@ contract('ETHTornado', (accounts) => { describe('snark proof verification on js side', () => { it('should detect tampering', async () => { const deposit = generateDeposit() - await tree.insert(deposit.commitment) - const { root, path_elements, path_index } = await tree.path(0) + tree.insert(deposit.commitment) + const { pathElements, pathIndices } = tree.path(0) const input = stringifyBigInts({ - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), nullifier: deposit.nullifier, relayer: operator, @@ -125,8 +124,8 @@ contract('ETHTornado', (accounts) => { fee, refund, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) let proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -159,7 +158,7 @@ contract('ETHTornado', (accounts) => { it('should work', async () => { const deposit = generateDeposit() const user = accounts[4] - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) const balanceUserBefore = await web3.eth.getBalance(user) @@ -171,12 +170,12 @@ contract('ETHTornado', (accounts) => { const balanceUserAfter = await web3.eth.getBalance(user) balanceUserAfter.should.be.eq.BN(toBN(balanceUserBefore).sub(toBN(value))) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) // Circuit input const input = stringifyBigInts({ // public - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), relayer: operator, recipient, @@ -186,8 +185,8 @@ contract('ETHTornado', (accounts) => { // private nullifier: deposit.nullifier, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -233,13 +232,13 @@ contract('ETHTornado', (accounts) => { it('should prevent double spend', async () => { const deposit = generateDeposit() - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await tornado.deposit(toFixedHex(deposit.commitment), { value, from: sender }) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) const input = stringifyBigInts({ - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), nullifier: deposit.nullifier, relayer: operator, @@ -247,8 +246,8 @@ contract('ETHTornado', (accounts) => { fee, refund, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) const { proof } = websnarkUtils.toSolidityInput(proofData) @@ -267,13 +266,13 @@ contract('ETHTornado', (accounts) => { it('should prevent double spend with overflow', async () => { const deposit = generateDeposit() - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await tornado.deposit(toFixedHex(deposit.commitment), { value, from: sender }) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) const input = stringifyBigInts({ - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), nullifier: deposit.nullifier, relayer: operator, @@ -281,8 +280,8 @@ contract('ETHTornado', (accounts) => { fee, refund, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) const { proof } = websnarkUtils.toSolidityInput(proofData) @@ -304,13 +303,13 @@ contract('ETHTornado', (accounts) => { it('fee should be less or equal transfer value', async () => { const deposit = generateDeposit() - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await tornado.deposit(toFixedHex(deposit.commitment), { value, from: sender }) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) const largeFee = bigInt(value).add(bigInt(1)) const input = stringifyBigInts({ - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), nullifier: deposit.nullifier, relayer: operator, @@ -318,8 +317,8 @@ contract('ETHTornado', (accounts) => { fee: largeFee, refund, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -338,22 +337,22 @@ contract('ETHTornado', (accounts) => { it('should throw for corrupted merkle tree root', async () => { const deposit = generateDeposit() - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await tornado.deposit(toFixedHex(deposit.commitment), { value, from: sender }) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) const input = stringifyBigInts({ nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), - root, + root: tree.root(), nullifier: deposit.nullifier, relayer: operator, recipient, fee, refund, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -373,13 +372,13 @@ contract('ETHTornado', (accounts) => { it('should reject with tampered public inputs', async () => { const deposit = generateDeposit() - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await tornado.deposit(toFixedHex(deposit.commitment), { value, from: sender }) - let { root, path_elements, path_index } = await tree.path(0) + let { pathElements, pathIndices } = tree.path(0) const input = stringifyBigInts({ - root, + root: tree.root(), nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), nullifier: deposit.nullifier, relayer: operator, @@ -387,8 +386,8 @@ contract('ETHTornado', (accounts) => { fee, refund, secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) let { proof } = websnarkUtils.toSolidityInput(proofData) @@ -449,22 +448,22 @@ contract('ETHTornado', (accounts) => { it('should reject with non zero refund', async () => { const deposit = generateDeposit() - await tree.insert(deposit.commitment) + tree.insert(deposit.commitment) await tornado.deposit(toFixedHex(deposit.commitment), { value, from: sender }) - const { root, path_elements, path_index } = await tree.path(0) + const { pathElements, pathIndices } = tree.path(0) const input = stringifyBigInts({ nullifierHash: pedersenHash(deposit.nullifier.leInt2Buff(31)), - root, + root: tree.root(), nullifier: deposit.nullifier, relayer: operator, recipient, fee, refund: bigInt(1), secret: deposit.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -487,17 +486,17 @@ contract('ETHTornado', (accounts) => { it('should work', async () => { const deposit1 = generateDeposit() const deposit2 = generateDeposit() - await tree.insert(deposit1.commitment) - await tree.insert(deposit2.commitment) + tree.insert(deposit1.commitment) + tree.insert(deposit2.commitment) await tornado.deposit(toFixedHex(deposit1.commitment), { value, gasPrice: '0' }) await tornado.deposit(toFixedHex(deposit2.commitment), { value, gasPrice: '0' }) - const { root, path_elements, path_index } = await tree.path(1) + const { pathElements, pathIndices } = tree.path(1) // Circuit input const input = stringifyBigInts({ // public - root, + root: tree.root(), nullifierHash: pedersenHash(deposit2.nullifier.leInt2Buff(31)), relayer: operator, recipient, @@ -507,8 +506,8 @@ contract('ETHTornado', (accounts) => { // private nullifier: deposit2.nullifier, secret: deposit2.secret, - pathElements: path_elements, - pathIndices: path_index, + pathElements: pathElements, + pathIndices: pathIndices, }) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) @@ -536,6 +535,6 @@ contract('ETHTornado', (accounts) => { await revertSnapshot(snapshotId.result) // eslint-disable-next-line require-atomic-updates snapshotId = await takeSnapshot() - tree = new MerkleTree(levels, null, prefix) + tree = new MerkleTree(levels) }) }) diff --git a/test/MerkleTreeWithHistory.test.js b/test/MerkleTreeWithHistory.test.js index 0be19f6..90aab40 100644 --- a/test/MerkleTreeWithHistory.test.js +++ b/test/MerkleTreeWithHistory.test.js @@ -1,4 +1,4 @@ -/* global artifacts, web3, contract, assert */ +/* global artifacts, web3, contract */ require('chai').use(require('bn-chai')(web3.utils.BN)).use(require('chai-as-promised')).should() const { takeSnapshot, revertSnapshot } = require('../lib/ganacheHelper') @@ -6,8 +6,7 @@ const { takeSnapshot, revertSnapshot } = require('../lib/ganacheHelper') const MerkleTreeWithHistory = artifacts.require('./MerkleTreeWithHistoryMock.sol') const hasherContract = artifacts.require('./Hasher.sol') -const MerkleTree = require('../lib/MerkleTree') -const hasherImpl = require('../lib/MiMC') +const MerkleTree = require('fixed-merkle-tree') const snarkjs = require('snarkjs') const bigInt = snarkjs.bigInt @@ -38,12 +37,10 @@ contract('MerkleTreeWithHistory', (accounts) => { // eslint-disable-next-line no-unused-vars const value = ETH_AMOUNT || '1000000000000000000' let snapshotId - let prefix = 'test' let tree - let hasher before(async () => { - tree = new MerkleTree(levels, null, prefix) + tree = new MerkleTree(levels) hasherInstance = await hasherContract.deployed() merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels, hasherInstance.address) snapshotId = await takeSnapshot() @@ -59,94 +56,15 @@ contract('MerkleTreeWithHistory', (accounts) => { }) }) - describe('merkleTreeLib', () => { - it('index_to_key', () => { - assert.equal(MerkleTree.index_to_key('test', 5, 20), 'test_tree_5_20') - }) - - it('tests insert', async () => { - hasher = new hasherImpl() - tree = new MerkleTree(2, null, prefix) - await tree.insert(toFixedHex('5')) - let { root, path_elements } = await tree.path(0) - const calculated_root = hasher.hash(null, hasher.hash(null, '5', path_elements[0]), path_elements[1]) - // console.log(root) - assert.equal(root, calculated_root) - }) - it('creation odd elements count', async () => { - const elements = [12, 13, 14, 15, 16, 17, 18, 19, 20] - for (const [, el] of Object.entries(elements)) { - await tree.insert(el) - } - - const batchTree = new MerkleTree(levels, elements, prefix) - for (const [i] of Object.entries(elements)) { - const pathViaConstructor = await batchTree.path(i) - const pathViaUpdate = await tree.path(i) - pathViaConstructor.should.be.deep.equal(pathViaUpdate) - } - }) - - it('should find an element', async () => { - const elements = [12, 13, 14, 15, 16, 17, 18, 19, 20] - for (const [, el] of Object.entries(elements)) { - await tree.insert(el) - } - let index = tree.getIndexByElement(13) - index.should.be.equal(1) - - index = tree.getIndexByElement(19) - index.should.be.equal(7) - - index = tree.getIndexByElement(12) - index.should.be.equal(0) - - index = tree.getIndexByElement(20) - index.should.be.equal(8) - - index = tree.getIndexByElement(42) - index.should.be.equal(false) - }) - - it('creation even elements count', async () => { - const elements = [12, 13, 14, 15, 16, 17] - for (const [, el] of Object.entries(elements)) { - await tree.insert(el) - } - - const batchTree = new MerkleTree(levels, elements, prefix) - for (const [i] of Object.entries(elements)) { - const pathViaConstructor = await batchTree.path(i) - const pathViaUpdate = await tree.path(i) - pathViaConstructor.should.be.deep.equal(pathViaUpdate) - } - }) - - it.skip('creation using 30000 elements', () => { - const elements = [] - for (let i = 1000; i < 31001; i++) { - elements.push(i) - } - console.time('MerkleTree') - tree = new MerkleTree(levels, elements, prefix) - console.timeEnd('MerkleTree') - // 2,7 GHz Intel Core i7 - // 1000 : 1949.084ms - // 10000: 19456.220ms - // 30000: 63406.679ms - }) - }) - describe('#insert', () => { it('should insert', async () => { let rootFromContract for (let i = 1; i < 11; i++) { await merkleTreeWithHistory.insert(toFixedHex(i), { from: sender }) - await tree.insert(i) - let { root } = await tree.path(i - 1) + tree.insert(i) rootFromContract = await merkleTreeWithHistory.getLastRoot() - toFixedHex(root).should.be.equal(rootFromContract.toString()) + toFixedHex(tree.root()).should.be.equal(rootFromContract.toString()) } }) @@ -177,19 +95,16 @@ contract('MerkleTreeWithHistory', (accounts) => { describe('#isKnownRoot', () => { it('should work', async () => { - let path - for (let i = 1; i < 5; i++) { await merkleTreeWithHistory.insert(toFixedHex(i), { from: sender }).should.be.fulfilled await tree.insert(i) - path = await tree.path(i - 1) - let isKnown = await merkleTreeWithHistory.isKnownRoot(toFixedHex(path.root)) + let isKnown = await merkleTreeWithHistory.isKnownRoot(toFixedHex(tree.root())) isKnown.should.be.equal(true) } await merkleTreeWithHistory.insert(toFixedHex(42), { from: sender }).should.be.fulfilled // check outdated root - let isKnown = await merkleTreeWithHistory.isKnownRoot(toFixedHex(path.root)) + let isKnown = await merkleTreeWithHistory.isKnownRoot(toFixedHex(tree.root())) isKnown.should.be.equal(true) }) @@ -204,7 +119,6 @@ contract('MerkleTreeWithHistory', (accounts) => { await revertSnapshot(snapshotId.result) // eslint-disable-next-line require-atomic-updates snapshotId = await takeSnapshot() - hasher = new hasherImpl() - tree = new MerkleTree(levels, null, prefix, null, hasher) + tree = new MerkleTree(levels) }) }) diff --git a/yarn.lock b/yarn.lock index a2b607d..01e43bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -622,6 +622,22 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@ethereumjs/common@^2.3.0", "@ethereumjs/common@^2.4.0", "@ethereumjs/common@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268" + integrity sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.1" + +"@ethereumjs/tx@^3.2.1": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.2.tgz#348d4624bf248aaab6c44fec2ae67265efe3db00" + integrity sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog== + dependencies: + "@ethereumjs/common" "^2.5.0" + ethereumjs-util "^7.1.2" + "@ethersproject/abi@5.0.0-beta.153": version "5.0.0-beta.153" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" @@ -1643,6 +1659,13 @@ dependencies: "@types/node" "*" +"@types/bn.js@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== + dependencies: + "@types/node" "*" + "@types/body-parser@*", "@types/body-parser@1.19.0": version "1.19.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" @@ -3313,6 +3336,16 @@ circom@^0.0.35: optimist "^0.6.1" yargs "^12.0.2" +"circomlib@git+https://github.com/tornadocash/circomlib.git#5beb6aee94923052faeecea40135d45b6ce6172c": + version "0.0.20" + resolved "git+https://github.com/tornadocash/circomlib.git#5beb6aee94923052faeecea40135d45b6ce6172c" + dependencies: + blake-hash "^1.1.0" + blake2b "^2.1.3" + snarkjs "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5" + typedarray-to-buffer "^3.1.5" + web3 "^1.2.11" + "circomlib@git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc": version "0.0.20" resolved "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc" @@ -3624,6 +3657,14 @@ cors@^2.8.1, cors@^2.8.4: object-assign "^4" vary "^1" +crc-32@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" + integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -4931,6 +4972,17 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereum rlp "^2.0.0" safe-buffer "^5.1.1" +ethereumjs-util@^7.0.10, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz#b55d7b64dde3e3e45749e4c41288238edec32d23" + integrity sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw== + 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" + ethereumjs-util@^7.0.2: version "7.0.7" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.7.tgz#484fb9c03b766b2ee64821281070616562fb5a59" @@ -5063,6 +5115,11 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -5383,6 +5440,14 @@ first-chunk-stream@^1.0.0: resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= +fixed-merkle-tree@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/fixed-merkle-tree/-/fixed-merkle-tree-0.6.0.tgz#523afc95836999bc7962ad3871afd2a1f2f78e04" + integrity sha512-qxY7IQuiIE7l/bKIFcgS8ZdHUwNapaE+HwELw6h0QBZ4V+6tqdea6z8iAFKO7B90ZgVfyoj4evAIMsd+J9HN0g== + dependencies: + circomlib "git+https://github.com/tornadocash/circomlib.git#5beb6aee94923052faeecea40135d45b6ce6172c" + snarkjs "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5" + flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -8962,6 +9027,11 @@ prettier@^2.2.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== +printj@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== + process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" @@ -11127,6 +11197,15 @@ web3-bzz@1.3.4: swarm-js "^0.1.40" underscore "1.9.1" +web3-bzz@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.6.0.tgz#584b51339f21eedff159abc9239b4b7ef6ded840" + integrity sha512-ugYV6BsinwhIi0CsLWINBz4mqN9wR9vNG0WmyEbdECjxcPyr6vkaWt4qi0zqlUxEnYAwGj4EJXNrbjPILntQTQ== + dependencies: + "@types/node" "^12.12.6" + got "9.6.0" + swarm-js "^0.1.40" + web3-core-helpers@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.9.tgz#6381077c3e01c127018cb9e9e3d1422697123315" @@ -11154,6 +11233,14 @@ web3-core-helpers@1.3.4: web3-eth-iban "1.3.4" web3-utils "1.3.4" +web3-core-helpers@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.6.0.tgz#77e161b6ba930a4008a0df804ab379e0aa7e1e7f" + integrity sha512-H/IAH/0mrgvad/oxVKiAMC7qDzMrPPe/nRKmJOoIsupRg9/frvL62kZZiHhqVD1HMyyswbQFC69QRl7JqWzvxg== + dependencies: + web3-eth-iban "1.6.0" + web3-utils "1.6.0" + web3-core-method@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.9.tgz#3fb538751029bea570e4f86731e2fa5e4945e462" @@ -11190,6 +11277,18 @@ web3-core-method@1.3.4: web3-core-subscriptions "1.3.4" web3-utils "1.3.4" +web3-core-method@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.6.0.tgz#ebe4ea51f5a4fa809bb68185576186359d3982e9" + integrity sha512-cHekyEil4mtcCOk6Q1Zh4y+2o5pTwsLIxP6Bpt4BRtZgdsyPiadYJpkLAVT/quch5xN7Qs5ZwG5AvRCS3VwD2g== + dependencies: + "@ethereumjs/common" "^2.4.0" + "@ethersproject/transactions" "^5.0.0-beta.135" + web3-core-helpers "1.6.0" + web3-core-promievent "1.6.0" + web3-core-subscriptions "1.6.0" + web3-utils "1.6.0" + web3-core-promievent@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.9.tgz#bb1c56aa6fac2f4b3c598510f06554d25c11c553" @@ -11211,6 +11310,13 @@ web3-core-promievent@1.3.4: dependencies: eventemitter3 "4.0.4" +web3-core-promievent@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.6.0.tgz#8b6053ae83cb47164540167fc361469fc604d2dd" + integrity sha512-ZzsevjMXWkhqW9dnVfTfb1OUcK7jKcKPvPIbQ4boJccNgvNZPZKlo8xB4pkAX38n4c59O5mC7Lt/z2QL/M5CeQ== + dependencies: + eventemitter3 "4.0.4" + web3-core-requestmanager@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.9.tgz#dd6d855256c4dd681434fe0867f8cd742fe10503" @@ -11246,6 +11352,17 @@ web3-core-requestmanager@1.3.4: web3-providers-ipc "1.3.4" web3-providers-ws "1.3.4" +web3-core-requestmanager@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.6.0.tgz#8ef3a3b89cd08983bd94574f9c5893f70a8a6aea" + integrity sha512-CY5paPdiDXKTXPWaEUZekDfUXSuoE2vPxolwqzsvKwFWH5+H1NaXgrc+D5HpufgSvTXawTw0fy7IAicg8+PWqA== + dependencies: + util "^0.12.0" + web3-core-helpers "1.6.0" + web3-providers-http "1.6.0" + web3-providers-ipc "1.6.0" + web3-providers-ws "1.6.0" + web3-core-subscriptions@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.9.tgz#335fd7d15dfce5d78b4b7bef05ce4b3d7237b0e4" @@ -11273,6 +11390,14 @@ web3-core-subscriptions@1.3.4: underscore "1.9.1" web3-core-helpers "1.3.4" +web3-core-subscriptions@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.6.0.tgz#8c23b15b434a7c9f937652ecca45d7108e2c54df" + integrity sha512-kY9WZUY/m1URSOv3uTLshoZD9ZDiFKReIzHuPUkxFpD5oYNmr1/aPQNPCrrMxKODR7UVX/D90FxWwCYqHhLaxQ== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.6.0" + web3-core@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.9.tgz#2cba57aa259b6409db532d21bdf57db8d504fd3e" @@ -11312,6 +11437,19 @@ web3-core@1.3.4: web3-core-requestmanager "1.3.4" web3-utils "1.3.4" +web3-core@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.6.0.tgz#144eb00f651c9812faf7176abd7ee99d5f45e212" + integrity sha512-o0WsLrJ2yD+HAAc29lGMWJef/MutTyuzpJC0UzLJtIAQJqtpDalzWINEu4j8XYXGk34N/V6vudtzRPo23QEE6g== + dependencies: + "@types/bn.js" "^4.11.5" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.6.0" + web3-core-method "1.6.0" + web3-core-requestmanager "1.6.0" + web3-utils "1.6.0" + web3-eth-abi@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.9.tgz#14bedd7e4be04fcca35b2ac84af1400574cd8280" @@ -11339,6 +11477,14 @@ web3-eth-abi@1.3.4: underscore "1.9.1" web3-utils "1.3.4" +web3-eth-abi@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.6.0.tgz#4225608f61ebb0607d80849bb2b20f910780253d" + integrity sha512-fImomGE9McuTMJLwK8Tp0lTUzXqCkWeMm00qPVIwpJ/h7lCw9UFYV9+4m29wSqW6FF+FIZKwc6UBEf9dlx3orA== + dependencies: + "@ethersproject/abi" "5.0.7" + web3-utils "1.6.0" + web3-eth-accounts@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.9.tgz#7ec422df90fecb5243603ea49dc28726db7bdab6" @@ -11390,6 +11536,23 @@ web3-eth-accounts@1.3.4: web3-core-method "1.3.4" web3-utils "1.3.4" +web3-eth-accounts@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.6.0.tgz#530927f4c5b78df93b3ea1203abbb467de29cd04" + integrity sha512-2f6HS4KIH4laAsNCOfbNX3dRiQosqSY2TRK86C8jtAA/QKGdx+5qlPfYzbI2RjG81iayb2+mVbHIaEaBGZ8sGw== + dependencies: + "@ethereumjs/common" "^2.3.0" + "@ethereumjs/tx" "^3.2.1" + crypto-browserify "3.12.0" + eth-lib "0.2.8" + ethereumjs-util "^7.0.10" + scrypt-js "^3.0.1" + uuid "3.3.2" + web3-core "1.6.0" + web3-core-helpers "1.6.0" + web3-core-method "1.6.0" + web3-utils "1.6.0" + web3-eth-contract@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.9.tgz#713d9c6d502d8c8f22b696b7ffd8e254444e6bfd" @@ -11435,6 +11598,20 @@ web3-eth-contract@1.3.4: web3-eth-abi "1.3.4" web3-utils "1.3.4" +web3-eth-contract@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.6.0.tgz#deb946867ad86d32bcbba899d733b681b25ea674" + integrity sha512-ZUtO77zFnxuFtrc+D+iJ3AzNgFXAVcKnhEYN7f1PNz/mFjbtE6dJ+ujO0mvMbxIZF02t9IZv0CIXRpK0rDvZAw== + dependencies: + "@types/bn.js" "^4.11.5" + web3-core "1.6.0" + web3-core-helpers "1.6.0" + web3-core-method "1.6.0" + web3-core-promievent "1.6.0" + web3-core-subscriptions "1.6.0" + web3-eth-abi "1.6.0" + web3-utils "1.6.0" + web3-eth-ens@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.9.tgz#577b9358c036337833fb2bdc59c11be7f6f731b6" @@ -11480,6 +11657,20 @@ web3-eth-ens@1.3.4: web3-eth-contract "1.3.4" web3-utils "1.3.4" +web3-eth-ens@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.6.0.tgz#af13852168d56fa71b9198eb097e96fb93831c2a" + integrity sha512-AG24PNv9qbYHSpjHcU2pViOII0jvIR7TeojJ2bxXSDqfcgHuRp3NZGKv6xFvT4uNI4LEQHUhSC7bzHoNF5t8CA== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.6.0" + web3-core-helpers "1.6.0" + web3-core-promievent "1.6.0" + web3-eth-abi "1.6.0" + web3-eth-contract "1.6.0" + web3-utils "1.6.0" + web3-eth-iban@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.9.tgz#4ebf3d8783f34d04c4740dc18938556466399f7a" @@ -11504,6 +11695,14 @@ web3-eth-iban@1.3.4: bn.js "^4.11.9" web3-utils "1.3.4" +web3-eth-iban@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.6.0.tgz#edbe46cedc5b148d53fa455edea6b4eef53b2be7" + integrity sha512-HM/bKBS/e8qg0+Eh7B8C/JVG+GkR4AJty17DKRuwMtrh78YsonPj7GKt99zS4n5sDLFww1Imu/ZIk3+K5uJCjw== + dependencies: + bn.js "^4.11.9" + web3-utils "1.6.0" + web3-eth-personal@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.9.tgz#9b95eb159b950b83cd8ae15873e1d57711b7a368" @@ -11540,6 +11739,18 @@ web3-eth-personal@1.3.4: web3-net "1.3.4" web3-utils "1.3.4" +web3-eth-personal@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.6.0.tgz#b75a61c0737b8b8bcc11d05db2ed7bfce7e4b262" + integrity sha512-8ohf4qAwbShf4RwES2tLHVqa+pHZnS5Q6tV80sU//bivmlZeyO1W4UWyNn59vu9KPpEYvLseOOC6Muxuvr8mFQ== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.6.0" + web3-core-helpers "1.6.0" + web3-core-method "1.6.0" + web3-net "1.6.0" + web3-utils "1.6.0" + web3-eth@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.9.tgz#e40e7b88baffc9b487193211c8b424dc944977b3" @@ -11597,6 +11808,24 @@ web3-eth@1.3.4: web3-net "1.3.4" web3-utils "1.3.4" +web3-eth@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.6.0.tgz#4c9d5fb4eccf9f8744828281757e6ea76af58cbd" + integrity sha512-qJMvai//r0be6I9ghU24/152f0zgJfYC23TMszN3Y6jse1JtjCBP2TlTibFcvkUN1RRdIUY5giqO7ZqAYAmp7w== + dependencies: + web3-core "1.6.0" + web3-core-helpers "1.6.0" + web3-core-method "1.6.0" + web3-core-subscriptions "1.6.0" + web3-eth-abi "1.6.0" + web3-eth-accounts "1.6.0" + web3-eth-contract "1.6.0" + web3-eth-ens "1.6.0" + web3-eth-iban "1.6.0" + web3-eth-personal "1.6.0" + web3-net "1.6.0" + web3-utils "1.6.0" + web3-net@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.9.tgz#51d248ed1bc5c37713c4ac40c0073d9beacd87d3" @@ -11624,6 +11853,15 @@ web3-net@1.3.4: web3-core-method "1.3.4" web3-utils "1.3.4" +web3-net@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.6.0.tgz#2c28f8787073110a7c2310336889d2dad647e500" + integrity sha512-LFfG95ovTT2sNHkO1TEfsaKpYcxOSUtbuwHQ0K3G0e5nevKDJkPEFIqIcob40yiwcWoqEjENJP9Bjk8CRrZ99Q== + dependencies: + web3-core "1.6.0" + web3-core-method "1.6.0" + web3-utils "1.6.0" + web3-providers-http@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.9.tgz#e698aa5377e2019c24c5a1e6efa0f51018728934" @@ -11648,6 +11886,14 @@ web3-providers-http@1.3.4: web3-core-helpers "1.3.4" xhr2-cookies "1.1.0" +web3-providers-http@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.6.0.tgz#8db4e589abf7197f5d65b12af1bf9726c45f4160" + integrity sha512-sNxHFNv3lnxpmULt34AS6M36IYB/Hzm2Et4yPNzdP1XE644D8sQBZQZaJQdTaza5HfrlwoqU6AOK935armqGuA== + dependencies: + web3-core-helpers "1.6.0" + xhr2-cookies "1.1.0" + web3-providers-ipc@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.9.tgz#6159eacfcd7ac31edc470d93ef10814fe874763b" @@ -11675,6 +11921,14 @@ web3-providers-ipc@1.3.4: underscore "1.9.1" web3-core-helpers "1.3.4" +web3-providers-ipc@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.6.0.tgz#6a3410fd47a67c4a36719fb97f99534ae12aac98" + integrity sha512-ETYdfhpGiGoWpmmSJnONvnPfd3TPivHEGjXyuX+L5FUsbMOVZj9MFLNIS19Cx/YGL8UWJ/8alLJoTcWSIdz/aA== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.6.0" + web3-providers-ws@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.9.tgz#22c2006655ec44b4ad2b41acae62741a6ae7a88c" @@ -11705,6 +11959,15 @@ web3-providers-ws@1.3.4: web3-core-helpers "1.3.4" websocket "^1.0.32" +web3-providers-ws@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.6.0.tgz#dc15dc18c30089efda992015fd5254bd2b77af5f" + integrity sha512-eNRmlhOPCpuVYwBrKBBQRLGPFb4U1Uo44r9EWV69Cpo4gP6XeBTl6nkawhLz6DS0fq79apyPfItJVuSfAy77pA== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.6.0" + websocket "^1.0.32" + web3-shh@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.9.tgz#c4ba70d6142cfd61341a50752d8cace9a0370911" @@ -11735,6 +11998,16 @@ web3-shh@1.3.4: web3-core-subscriptions "1.3.4" web3-net "1.3.4" +web3-shh@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.6.0.tgz#838a3435dce1039f669a48e53e948062de197931" + integrity sha512-ymN0OFL81WtEeSyb+PFpuUv39fR3frGwsZnIg5EVPZvrOIdaDSFcGSLDmafUt0vKSubvLMVYIBOCskRD6YdtEQ== + dependencies: + web3-core "1.6.0" + web3-core-method "1.6.0" + web3-core-subscriptions "1.6.0" + web3-net "1.6.0" + web3-utils@1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.9.tgz#abe11735221627da943971ef1a630868fb9c61f3" @@ -11777,6 +12050,19 @@ web3-utils@1.3.4, web3-utils@^1.3.4: underscore "1.9.1" utf8 "3.0.0" +web3-utils@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.6.0.tgz#1975c5ee5b7db8a0836eb7004848a7cd962d1ddc" + integrity sha512-bgCAWAeQnJF035YTFxrcHJ5mGEfTi/McsjqldZiXRwlHK7L1PyOqvXiQLE053dlzvy1kdAxWl/sSSfLMyNUAXg== + dependencies: + bn.js "^4.11.9" + ethereum-bloom-filters "^1.0.6" + ethereumjs-util "^7.1.0" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + web3@*, web3@^1.0.0-beta.34, web3@^1.0.0-beta.55: version "1.3.1" resolved "https://registry.yarnpkg.com/web3/-/web3-1.3.1.tgz#f780138c92ae3c42ea45e1a3c6ae8844e0aa5054" @@ -11803,6 +12089,19 @@ web3@1.2.9: web3-shh "1.2.9" web3-utils "1.2.9" +web3@^1.2.11: + version "1.6.0" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.6.0.tgz#d8fa0cd9e7bf252f9fe43bb77dc42bc6671affde" + integrity sha512-rWpXnO88MiVX5yTRqMBCVKASxc7QDkXZZUl1D48sKlbX4dt3BAV+nVMVUKCBKiluZ5Bp8pDrVCUdPx/jIYai5Q== + dependencies: + web3-bzz "1.6.0" + web3-core "1.6.0" + web3-eth "1.6.0" + web3-eth-personal "1.6.0" + web3-net "1.6.0" + web3-shh "1.6.0" + web3-utils "1.6.0" + web3@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/web3/-/web3-1.3.4.tgz#31e014873360aa5840eb17f9f171190c967cffb7"