From 780adf362632293c0af08e06384caf4305e3e32c Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 4 Feb 2021 17:17:21 +0300 Subject: [PATCH] WIP --- contracts/TornadoTrees.sol | 43 +++++++++++------- contracts/mocks/TornadoTreesV1Mock.sol | 63 ++++++++++++++++++++++++++ hardhat.config.js | 3 ++ test/tornadoTrees.test.js | 24 ++++++---- 4 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 contracts/mocks/TornadoTreesV1Mock.sol diff --git a/contracts/TornadoTrees.sol b/contracts/TornadoTrees.sol index c8b8106..0850dbe 100644 --- a/contracts/TornadoTrees.sol +++ b/contracts/TornadoTrees.sol @@ -7,6 +7,8 @@ import "torn-token/contracts/ENS.sol"; import "./interfaces/ITornadoTreesV1.sol"; import "./interfaces/IVerifier.sol"; +import "hardhat/console.sol"; + contract TornadoTrees is EnsResolve { address public immutable governance; bytes32 public depositRoot; @@ -75,35 +77,45 @@ contract TornadoTrees is EnsResolve { depositRoot = _tornadoTreesV1.depositRoot(); withdrawalRoot = _tornadoTreesV1.withdrawalRoot(); - uint256 _lastProcessedDepositLeaf = _tornadoTreesV1.lastProcessedDepositLeaf(); - require(_lastProcessedDepositLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees contract state"); - lastProcessedDepositLeaf = _lastProcessedDepositLeaf; + uint256 depositLeaf = _tornadoTreesV1.lastProcessedDepositLeaf(); + require(depositLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state"); + lastProcessedDepositLeaf = depositLeaf; - uint256 _lastProcessedWithdrawalLeaf = _tornadoTreesV1.lastProcessedWithdrawalLeaf(); - require(_lastProcessedWithdrawalLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees contract state"); - lastProcessedWithdrawalLeaf = _lastProcessedWithdrawalLeaf; + uint256 withdrawalLeaf = _tornadoTreesV1.lastProcessedWithdrawalLeaf(); + require(withdrawalLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state"); + lastProcessedWithdrawalLeaf = withdrawalLeaf; - uint256 i = _lastProcessedDepositLeaf + 1; + uint256 i = depositLeaf; - // todo deposits.length = _tornadoTreesV1.deposits.length + todo deposits.length = _tornadoTreesV1.deposits.length while (true) { - bytes32 deposit = _tornadoTreesV1.deposits(i); - if (deposit == bytes32(0)) { + (bool success, bytes memory data) = address(_tornadoTreesV1).call(abi.encodeWithSignature("deposits(uint256)", i)); + // console.log("success", success); + if (!success) { break; } + bytes32 deposit = abi.decode(data, (bytes32)); i++; deposits.push(deposit); } - i = _lastProcessedWithdrawalLeaf + 1; + uint256 j = withdrawalLeaf; while (true) { - bytes32 withdrawal = _tornadoTreesV1.withdrawals(i); - if (withdrawal == bytes32(0)) { + (bool success1, bytes memory data1) = address(_tornadoTreesV1).staticcall( + abi.encodeWithSignature("withdrawals(uint256)", j) + ); + // console.log("success", success); + // console.logBytes(data); + + if (!success1) { break; } - i++; + bytes32 withdrawal = abi.decode(data1, (bytes32)); + // console.logBytes32(withdrawal); + j++; withdrawals.push(withdrawal); } + console.log("end"); } function registerDeposit(address _instance, bytes32 _commitment) external onlyTornadoProxy onlyInitialized { @@ -149,9 +161,6 @@ contract TornadoTrees is EnsResolve { initialized = true; } - // если чтото загрузит руты на старый контракт во время миграции то пизда - - // todo !!! ensure that during migration the tree is filled evenly function updateDepositTree( bytes calldata _proof, bytes32 _argsHash, diff --git a/contracts/mocks/TornadoTreesV1Mock.sol b/contracts/mocks/TornadoTreesV1Mock.sol new file mode 100644 index 0000000..8ab0ac7 --- /dev/null +++ b/contracts/mocks/TornadoTreesV1Mock.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +contract TornadoTreesV1Mock { + uint256 public timestamp; + uint256 public currentBlock; + + bytes32[] public deposits; + uint256 public lastProcessedDepositLeaf; + + bytes32[] public withdrawals; + uint256 public lastProcessedWithdrawalLeaf; + + bytes32 public depositRoot; + bytes32 public withdrawalRoot; + + constructor( + uint256 _lastProcessedDepositLeaf, + uint256 _lastProcessedWithdrawalLeaf, + bytes32 _depositRoot, + bytes32 _withdrawalRoot + ) public { + lastProcessedDepositLeaf = _lastProcessedDepositLeaf; + lastProcessedWithdrawalLeaf = _lastProcessedWithdrawalLeaf; + depositRoot = _depositRoot; + withdrawalRoot = _withdrawalRoot; + } + + function register( + address _instance, + bytes32 _commitment, + bytes32 _nullifier, + uint256 _depositBlockNumber, + uint256 _withdrawBlockNumber + ) public { + setBlockNumber(_depositBlockNumber); + deposits.push(keccak256(abi.encode(_instance, _commitment, blockNumber()))); + setBlockNumber(_withdrawBlockNumber); + withdrawals.push(keccak256(abi.encode(_instance, _nullifier, blockNumber()))); + } + + function setLastProcessedDepositLeaf(uint256 _lastProcessedDepositLeaf) public { + lastProcessedDepositLeaf = _lastProcessedDepositLeaf; + } + + function setLastProcessedWithdrawalLeaf(uint256 _lastProcessedWithdrawalLeaf) public { + lastProcessedWithdrawalLeaf = _lastProcessedWithdrawalLeaf; + } + + function resolve(bytes32 _addr) public pure returns (address) { + return address(uint160(uint256(_addr) >> (12 * 8))); + } + + function setBlockNumber(uint256 _blockNumber) public { + currentBlock = _blockNumber; + } + + function blockNumber() public view returns (uint256) { + return currentBlock == 0 ? block.number : currentBlock; + } +} diff --git a/hardhat.config.js b/hardhat.config.js index a7ebedd..499aba2 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -20,6 +20,9 @@ task('accounts', 'Prints the list of accounts', async () => { module.exports = { solidity: '0.6.12', networks: { + hardhat: { + blockGasLimit: 950000000, + }, goerli: { url: `https://goerli.infura.io/v3/${process.env.INFURA_TOKEN}`, accounts: [process.env.PRIVATE_KEY], diff --git a/test/tornadoTrees.test.js b/test/tornadoTrees.test.js index c194b11..d32f356 100644 --- a/test/tornadoTrees.test.js +++ b/test/tornadoTrees.test.js @@ -36,6 +36,7 @@ describe('TornadoTrees', function () { let tornadoProxy let verifier let tornadoTrees + let tornadoTreesV1 let notes const depositEvents = [] const withdrawalEvents = [] @@ -47,14 +48,8 @@ describe('TornadoTrees', function () { const BatchTreeUpdateVerifier = await ethers.getContractFactory('BatchTreeUpdateVerifier') verifier = await BatchTreeUpdateVerifier.deploy() - const TornadoTrees = await ethers.getContractFactory('TornadoTreesMock') - tornadoTrees = await TornadoTrees.deploy( - toEns(operator.address), - toEns(tornadoProxy.address), - toEns(verifier.address), - toFixedHex(tree.root()), - toFixedHex(tree.root()), - ) + const TornadoTreesV1 = await ethers.getContractFactory('TornadoTreesV1Mock') + tornadoTreesV1 = await TornadoTreesV1.deploy(0, 0, tree.root(), tree.root()) notes = [] for (let i = 0; i < 2 ** CHUNK_TREE_HEIGHT; i++) { @@ -65,7 +60,7 @@ describe('TornadoTrees', function () { commitment: randomBN(), nullifierHash: randomBN(), } - await register(notes[i], tornadoTrees, tornadoProxy) + await register(notes[i], tornadoTreesV1, tornadoProxy) depositEvents[i] = { hash: toFixedHex(notes[i].commitment), instance: toFixedHex(notes[i].instance, 20), @@ -77,6 +72,15 @@ describe('TornadoTrees', function () { block: toFixedHex(notes[i].withdrawalBlock, 4), } } + const TornadoTrees = await ethers.getContractFactory('TornadoTreesMock') + tornadoTrees = await TornadoTrees.deploy( + operator.address, + tornadoProxy.address, + tornadoTreesV1.address, + verifier.address, + // { gasLimit: 30e6 }, + ) + await tornadoTrees.migrate(depositEvents, withdrawalEvents) }) describe('#updateDepositTree', () => { @@ -86,7 +90,7 @@ describe('TornadoTrees', function () { expect(solHash).to.be.equal(args[0]) }) - it('should prove snark', async () => { + it.only('should prove snark', async () => { const { input, args } = controller.batchTreeUpdate(tree, depositEvents) const proof = await controller.prove(input, './artifacts/circuits/BatchTreeUpdate') await tornadoTrees.updateDepositTree(proof, ...args)