From 1fdabcc97c173d1890487a5f216bb82e81ef9ca2 Mon Sep 17 00:00:00 2001 From: poma Date: Sat, 2 Nov 2019 15:35:22 +0300 Subject: [PATCH] changed emptyElement to constant --- .env.example | 1 - cli.js | 8 +++----- contracts/ERC20Mixer.sol | 3 +-- contracts/ETHMixer.sol | 3 +-- contracts/MerkleTreeWithHistory.sol | 11 ++++++----- contracts/Mixer.sol | 4 +--- contracts/Mocks/MerkleTreeWithHistoryMock.sol | 2 +- lib/MerkleTree.js | 5 +++-- migrations/4_deploy_eth_mixer.js | 4 ++-- migrations/5_deploy_erc20_mixer.js | 3 +-- test/ERC20Mixer.test.js | 5 +---- test/ETHMixer.test.js | 5 +---- test/MerkleTreeWithHistory.test.js | 19 ++++++------------- 13 files changed, 27 insertions(+), 46 deletions(-) diff --git a/.env.example b/.env.example index 7fdb12d..20f30fd 100644 --- a/.env.example +++ b/.env.example @@ -2,7 +2,6 @@ MERKLE_TREE_HEIGHT=16 # in wei ETH_AMOUNT=100000000000000000 TOKEN_AMOUNT=100000000000000000 -EMPTY_ELEMENT=1 PRIVATE_KEY= ERC20_TOKEN= diff --git a/cli.js b/cli.js index e2e9c2b..0a23426 100755 --- a/cli.js +++ b/cli.js @@ -13,7 +13,7 @@ const buildGroth16 = require('websnark/src/groth16') const websnarkUtils = require('websnark/src/utils') let web3, mixer, erc20mixer, circuit, proving_key, groth16, erc20 -let MERKLE_TREE_HEIGHT, ETH_AMOUNT, EMPTY_ELEMENT, ERC20_TOKEN +let MERKLE_TREE_HEIGHT, ETH_AMOUNT, ERC20_TOKEN const inBrowser = (typeof window !== 'undefined') /** Generate random number of specified byte length */ @@ -83,7 +83,7 @@ async function withdrawErc20(note, receiver, relayer) { } return e.returnValues.commitment }) - const tree = new merkleTree(MERKLE_TREE_HEIGHT, EMPTY_ELEMENT, leaves) + const tree = new merkleTree(MERKLE_TREE_HEIGHT, leaves) const validRoot = await erc20mixer.methods.isKnownRoot(await tree.root()).call() const nullifierHash = pedersenHash(deposit.nullifier.leInt2Buff(31)) const nullifierHashToCheck = nullifierHash.toString(16).padStart('66', '0x000000') @@ -152,7 +152,7 @@ async function withdraw(note, receiver) { const leaves = events .sort((a, b) => a.returnValues.leafIndex.sub(b.returnValues.leafIndex)) // Sort events in chronological order .map(e => e.returnValues.commitment) - const tree = new merkleTree(MERKLE_TREE_HEIGHT, EMPTY_ELEMENT, leaves) + const tree = new merkleTree(MERKLE_TREE_HEIGHT, leaves) // Find current commitment in the tree let depositEvent = events.find(e => e.returnValues.commitment.eq(paddedCommitment)) @@ -210,7 +210,6 @@ async function init() { proving_key = await (await fetch('build/circuits/withdraw_proving_key.bin')).arrayBuffer() MERKLE_TREE_HEIGHT = 16 ETH_AMOUNT = 1e18 - EMPTY_ELEMENT = 1 } else { // Initialize from local node web3 = new Web3('http://localhost:8545', null, { transactionConfirmationBlocks: 1 }) @@ -220,7 +219,6 @@ async function init() { require('dotenv').config() MERKLE_TREE_HEIGHT = process.env.MERKLE_TREE_HEIGHT ETH_AMOUNT = process.env.ETH_AMOUNT - EMPTY_ELEMENT = process.env.EMPTY_ELEMENT ERC20_TOKEN = process.env.ERC20_TOKEN erc20ContractJson = require('./build/contracts/ERC20Mock.json') erc20mixerJson = require('./build/contracts/ERC20Mixer.json') diff --git a/contracts/ERC20Mixer.sol b/contracts/ERC20Mixer.sol index a7c6c58..46cbb35 100644 --- a/contracts/ERC20Mixer.sol +++ b/contracts/ERC20Mixer.sol @@ -20,10 +20,9 @@ contract ERC20Mixer is Mixer { IVerifier _verifier, uint256 _denomination, uint8 _merkleTreeHeight, - uint256 _emptyElement, address _operator, address _token - ) Mixer(_verifier, _denomination, _merkleTreeHeight, _emptyElement, _operator) public { + ) Mixer(_verifier, _denomination, _merkleTreeHeight, _operator) public { token = _token; } diff --git a/contracts/ETHMixer.sol b/contracts/ETHMixer.sol index 56a9aed..188dbb2 100644 --- a/contracts/ETHMixer.sol +++ b/contracts/ETHMixer.sol @@ -18,9 +18,8 @@ contract ETHMixer is Mixer { IVerifier _verifier, uint256 _denomination, uint8 _merkleTreeHeight, - uint256 _emptyElement, address _operator - ) Mixer(_verifier, _denomination, _merkleTreeHeight, _emptyElement, _operator) public { + ) Mixer(_verifier, _denomination, _merkleTreeHeight, _operator) public { } function _processWithdraw(address payable _receiver, address payable _relayer, uint256 _fee, uint256 _refund) internal { diff --git a/contracts/MerkleTreeWithHistory.sol b/contracts/MerkleTreeWithHistory.sol index 0deb5a7..39c18a6 100644 --- a/contracts/MerkleTreeWithHistory.sol +++ b/contracts/MerkleTreeWithHistory.sol @@ -18,8 +18,9 @@ library Hasher { contract MerkleTreeWithHistory { uint256 public levels; - uint256 constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - uint256 constant ROOT_HISTORY_SIZE = 100; + uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint256 public constant ZERO_VALUE = 5702960885942360421128284892092891246826997279710054143430547229469817701242; // = MiMC("tornado") + uint256 public constant ROOT_HISTORY_SIZE = 100; uint256[ROOT_HISTORY_SIZE] public _roots; uint256 public current_root_index = 0; @@ -28,12 +29,12 @@ contract MerkleTreeWithHistory { uint32 public next_index = 0; - constructor(uint256 tree_levels, uint256 zero_value) public { + constructor(uint256 tree_levels) public { require(tree_levels > 0, "tree_levels should be greater than zero"); levels = tree_levels; - uint256 current_zero = zero_value; - _zeros.push(zero_value); + uint256 current_zero = ZERO_VALUE; + _zeros.push(ZERO_VALUE); _filled_subtrees.push(current_zero); for (uint8 i = 1; i < levels; i++) { diff --git a/contracts/Mixer.sol b/contracts/Mixer.sol index 223c3e0..11e2541 100644 --- a/contracts/Mixer.sol +++ b/contracts/Mixer.sol @@ -43,16 +43,14 @@ contract Mixer is MerkleTreeWithHistory { @dev The constructor @param _verifier the address of SNARK verifier for this contract @param _merkleTreeHeight the height of deposits' Merkle Tree - @param _emptyElement default element of the deposits' Merkle Tree @param _operator operator address (see operator above) */ constructor( IVerifier _verifier, uint256 _denomination, uint8 _merkleTreeHeight, - uint256 _emptyElement, address _operator - ) MerkleTreeWithHistory(_merkleTreeHeight, _emptyElement) public { + ) MerkleTreeWithHistory(_merkleTreeHeight) public { require(_denomination > 0, "denomination should be greater than 0"); verifier = _verifier; operator = _operator; diff --git a/contracts/Mocks/MerkleTreeWithHistoryMock.sol b/contracts/Mocks/MerkleTreeWithHistoryMock.sol index 0029b44..1b98af7 100644 --- a/contracts/Mocks/MerkleTreeWithHistoryMock.sol +++ b/contracts/Mocks/MerkleTreeWithHistoryMock.sol @@ -4,7 +4,7 @@ import '../MerkleTreeWithHistory.sol'; contract MerkleTreeWithHistoryMock is MerkleTreeWithHistory { - constructor (uint8 tree_levels, uint256 zero_value) MerkleTreeWithHistory(tree_levels, zero_value) public {} + constructor (uint8 tree_levels) MerkleTreeWithHistory(tree_levels) public {} function insert(uint256 leaf) public { _insert(leaf); diff --git a/lib/MerkleTree.js b/lib/MerkleTree.js index f18f6f3..05b97ff 100644 --- a/lib/MerkleTree.js +++ b/lib/MerkleTree.js @@ -1,9 +1,10 @@ const jsStorage = require('./Storage') const hasherImpl = require('./MiMC') +const { bigInt } = require('snarkjs') class MerkleTree { - constructor(n_levels, zero_value, defaultElements, prefix, storage, hasher) { + constructor(n_levels, defaultElements, prefix, storage, hasher) { this.prefix = prefix this.storage = storage || new jsStorage() this.hasher = hasher || new hasherImpl() @@ -11,7 +12,7 @@ class MerkleTree { this.zero_values = [] this.totalElements = 0 - let current_zero_value = zero_value || 0 + let current_zero_value = bigInt('5702960885942360421128284892092891246826997279710054143430547229469817701242') 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) diff --git a/migrations/4_deploy_eth_mixer.js b/migrations/4_deploy_eth_mixer.js index 6100b04..2a2d48c 100644 --- a/migrations/4_deploy_eth_mixer.js +++ b/migrations/4_deploy_eth_mixer.js @@ -7,11 +7,11 @@ const hasherContract = artifacts.require('Hasher') module.exports = function(deployer, network, accounts) { return deployer.then(async () => { - const { MERKLE_TREE_HEIGHT, ETH_AMOUNT, EMPTY_ELEMENT } = process.env + const { MERKLE_TREE_HEIGHT, ETH_AMOUNT } = process.env const verifier = await Verifier.deployed() const hasherInstance = await hasherContract.deployed() await ETHMixer.link(hasherContract, hasherInstance.address) - const mixer = await deployer.deploy(ETHMixer, verifier.address, ETH_AMOUNT, MERKLE_TREE_HEIGHT, EMPTY_ELEMENT, accounts[0]) + const mixer = await deployer.deploy(ETHMixer, verifier.address, ETH_AMOUNT, MERKLE_TREE_HEIGHT, accounts[0]) console.log('ETHMixer\'s address ', mixer.address) }) } diff --git a/migrations/5_deploy_erc20_mixer.js b/migrations/5_deploy_erc20_mixer.js index 03109fb..a4506c2 100644 --- a/migrations/5_deploy_erc20_mixer.js +++ b/migrations/5_deploy_erc20_mixer.js @@ -8,7 +8,7 @@ const ERC20Mock = artifacts.require('ERC20Mock') module.exports = function(deployer, network, accounts) { return deployer.then(async () => { - const { MERKLE_TREE_HEIGHT, EMPTY_ELEMENT, ERC20_TOKEN, TOKEN_AMOUNT } = process.env + const { MERKLE_TREE_HEIGHT, ERC20_TOKEN, TOKEN_AMOUNT } = process.env const verifier = await Verifier.deployed() const hasherInstance = await hasherContract.deployed() await ERC20Mixer.link(hasherContract, hasherInstance.address) @@ -22,7 +22,6 @@ module.exports = function(deployer, network, accounts) { verifier.address, TOKEN_AMOUNT, MERKLE_TREE_HEIGHT, - EMPTY_ELEMENT, accounts[0], token, ) diff --git a/test/ERC20Mixer.test.js b/test/ERC20Mixer.test.js index 534a062..87a0141 100644 --- a/test/ERC20Mixer.test.js +++ b/test/ERC20Mixer.test.js @@ -11,7 +11,7 @@ const { takeSnapshot, revertSnapshot } = require('../lib/ganacheHelper') const Mixer = artifacts.require('./ERC20Mixer.sol') const Token = artifacts.require('./ERC20Mock.sol') const USDTToken = artifacts.require('./IUSDT.sol') -const { ETH_AMOUNT, TOKEN_AMOUNT, MERKLE_TREE_HEIGHT, EMPTY_ELEMENT, ERC20_TOKEN } = process.env +const { ETH_AMOUNT, TOKEN_AMOUNT, MERKLE_TREE_HEIGHT, ERC20_TOKEN } = process.env const websnarkUtils = require('websnark/src/utils') const buildGroth16 = require('websnark/src/groth16') @@ -50,7 +50,6 @@ contract('ERC20Mixer', accounts => { const sender = accounts[0] const operator = accounts[0] const levels = MERKLE_TREE_HEIGHT || 16 - const zeroValue = EMPTY_ELEMENT || 1337 let tokenDenomination = TOKEN_AMOUNT || '1000000000000000000' // 1 ether let snapshotId let prefix = 'test' @@ -66,7 +65,6 @@ contract('ERC20Mixer', accounts => { before(async () => { tree = new MerkleTree( levels, - zeroValue, null, prefix, ) @@ -401,7 +399,6 @@ contract('ERC20Mixer', accounts => { snapshotId = await takeSnapshot() tree = new MerkleTree( levels, - zeroValue, null, prefix, ) diff --git a/test/ETHMixer.test.js b/test/ETHMixer.test.js index aa8f3a6..595014a 100644 --- a/test/ETHMixer.test.js +++ b/test/ETHMixer.test.js @@ -9,7 +9,7 @@ const { toBN, toHex, randomHex } = require('web3-utils') const { takeSnapshot, revertSnapshot } = require('../lib/ganacheHelper') const Mixer = artifacts.require('./ETHMixer.sol') -const { ETH_AMOUNT, MERKLE_TREE_HEIGHT, EMPTY_ELEMENT } = process.env +const { ETH_AMOUNT, MERKLE_TREE_HEIGHT } = process.env const websnarkUtils = require('websnark/src/utils') const buildGroth16 = require('websnark/src/groth16') @@ -62,7 +62,6 @@ contract('ETHMixer', accounts => { const sender = accounts[0] const operator = accounts[0] const levels = MERKLE_TREE_HEIGHT || 16 - const zeroValue = EMPTY_ELEMENT || 1337 const value = ETH_AMOUNT || '1000000000000000000' // 1 ether let snapshotId let prefix = 'test' @@ -78,7 +77,6 @@ contract('ETHMixer', accounts => { before(async () => { tree = new MerkleTree( levels, - zeroValue, null, prefix, ) @@ -521,7 +519,6 @@ contract('ETHMixer', accounts => { snapshotId = await takeSnapshot() tree = new MerkleTree( levels, - zeroValue, null, prefix, ) diff --git a/test/MerkleTreeWithHistory.test.js b/test/MerkleTreeWithHistory.test.js index 64c48d2..814f07c 100644 --- a/test/MerkleTreeWithHistory.test.js +++ b/test/MerkleTreeWithHistory.test.js @@ -12,7 +12,7 @@ const hasherContract = artifacts.require('./Hasher.sol') const MerkleTree = require('../lib/MerkleTree') const hasherImpl = require('../lib/MiMC') -const { ETH_AMOUNT, MERKLE_TREE_HEIGHT, EMPTY_ELEMENT } = process.env +const { ETH_AMOUNT, MERKLE_TREE_HEIGHT } = process.env // eslint-disable-next-line no-unused-vars function BNArrayToStringArray(array) { @@ -27,7 +27,6 @@ contract('MerkleTreeWithHistory', accounts => { let merkleTreeWithHistory let hasherInstance let levels = MERKLE_TREE_HEIGHT || 16 - let zeroValue = EMPTY_ELEMENT || 1337 const sender = accounts[0] // eslint-disable-next-line no-unused-vars const value = ETH_AMOUNT || '1000000000000000000' @@ -39,19 +38,19 @@ contract('MerkleTreeWithHistory', accounts => { before(async () => { tree = new MerkleTree( levels, - zeroValue, null, prefix, ) hasherInstance = await hasherContract.deployed() await MerkleTreeWithHistory.link(hasherContract, hasherInstance.address) - merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels, zeroValue) + merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels) snapshotId = await takeSnapshot() }) describe('#constructor', () => { it('should initialize', async () => { const filled_subtrees = await merkleTreeWithHistory.filled_subtrees() + const zeroValue = await merkleTreeWithHistory.ZERO_VALUE() filled_subtrees[0].should.be.eq.BN(zeroValue) const zeros = await merkleTreeWithHistory.zeros() zeros[0].should.be.eq.BN(zeroValue) @@ -70,7 +69,6 @@ contract('MerkleTreeWithHistory', accounts => { hasher = new hasherImpl() tree = new MerkleTree( 2, - zeroValue, null, prefix, ) @@ -91,7 +89,6 @@ contract('MerkleTreeWithHistory', accounts => { const batchTree = new MerkleTree( levels, - zeroValue, elements, prefix, ) @@ -131,7 +128,6 @@ contract('MerkleTreeWithHistory', accounts => { const batchTree = new MerkleTree( levels, - zeroValue, elements, prefix, ) @@ -150,7 +146,6 @@ contract('MerkleTreeWithHistory', accounts => { console.time('MerkleTree') tree = new MerkleTree( levels, - zeroValue, elements, prefix, ) @@ -177,8 +172,7 @@ contract('MerkleTreeWithHistory', accounts => { it('should reject if tree is full', async () => { levels = 6 - zeroValue = 1337 - merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels, zeroValue) + merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels) for (let i = 0; i < 2**levels; i++) { await merkleTreeWithHistory.insert(i+42).should.be.fulfilled @@ -193,8 +187,8 @@ contract('MerkleTreeWithHistory', accounts => { it.skip('hasher gas', async () => { levels = 6 - zeroValue = 1337 - merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels, zeroValue) + merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels) + const zeroValue = await merkleTreeWithHistory.zeroValue() const gas = await merkleTreeWithHistory.hashLeftRight.estimateGas(zeroValue, zeroValue) console.log('gas', gas - 21000) @@ -208,7 +202,6 @@ contract('MerkleTreeWithHistory', accounts => { hasher = new hasherImpl() tree = new MerkleTree( levels, - zeroValue, null, prefix, null,