Merge pull request #4 from tornadocash/fixTorando

Fix tornado
This commit is contained in:
Roman Storm 2021-01-11 11:52:27 -05:00 committed by GitHub
commit 94d43e31a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 692752 additions and 39 deletions

3
.gitignore vendored

@ -1,2 +1,3 @@
node_modules
.env
.env
.idea

687488
build/circuits/tornado.json Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

@ -0,0 +1,213 @@
[
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "_totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "address",
"name": "who",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"constant": true,
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "nonces",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]

@ -0,0 +1,519 @@
[
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "_newOperator",
"type": "address"
}
],
"name": "changeOperator",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "nullifierHashes",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "bytes",
"name": "_proof",
"type": "bytes"
},
{
"internalType": "bytes32",
"name": "_root",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_nullifierHash",
"type": "bytes32"
},
{
"internalType": "address payable",
"name": "_recipient",
"type": "address"
},
{
"internalType": "address payable",
"name": "_relayer",
"type": "address"
},
{
"internalType": "uint256",
"name": "_fee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_refund",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "verifier",
"outputs": [
{
"internalType": "contract IVerifier",
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "bytes32",
"name": "_left",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_right",
"type": "bytes32"
}
],
"name": "hashLeftRight",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "FIELD_SIZE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "levels",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "operator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "bytes32",
"name": "_root",
"type": "bytes32"
}
],
"name": "isKnownRoot",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "commitments",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "denomination",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentRootIndex",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "_newVerifier",
"type": "address"
}
],
"name": "updateVerifier",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "bytes32[]",
"name": "_nullifierHashes",
"type": "bytes32[]"
}
],
"name": "isSpentArray",
"outputs": [
{
"internalType": "bool[]",
"name": "spent",
"type": "bool[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "bytes32",
"name": "_commitment",
"type": "bytes32"
}
],
"name": "deposit",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getLastRoot",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "roots",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "ROOT_HISTORY_SIZE",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "bytes32",
"name": "_nullifierHash",
"type": "bytes32"
}
],
"name": "isSpent",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "zeros",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "ZERO_VALUE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "filledSubtrees",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "nextIndex",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IVerifier",
"name": "_verifier",
"type": "address"
},
{
"internalType": "uint256",
"name": "_denomination",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "_merkleTreeHeight",
"type": "uint32"
},
{
"internalType": "address",
"name": "_operator",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "commitment",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint32",
"name": "leafIndex",
"type": "uint32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "Deposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "nullifierHash",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "relayer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "fee",
"type": "uint256"
}
],
"name": "Withdrawal",
"type": "event"
}
]

@ -0,0 +1,237 @@
[
{
"inputs": [
{
"internalType": "bytes32",
"name": "_tornadoTrees",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_governance",
"type": "bytes32"
},
{
"internalType": "bytes32[]",
"name": "_instances",
"type": "bytes32[]"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes",
"name": "encryptedNote",
"type": "bytes"
}
],
"name": "EncryptedNote",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes32[]",
"name": "domains",
"type": "bytes32[]"
}
],
"name": "bulkResolve",
"outputs": [
{
"internalType": "address[]",
"name": "result",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "governance",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ITornadoInstance",
"name": "",
"type": "address"
}
],
"name": "instances",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "node",
"type": "bytes32"
}
],
"name": "resolve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tornadoTrees",
"outputs": [
{
"internalType": "contract ITornadoTrees",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ITornadoInstance",
"name": "_tornado",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_commitment",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "_encryptedNote",
"type": "bytes"
}
],
"name": "deposit",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ITornadoInstance",
"name": "_instance",
"type": "address"
},
{
"internalType": "bool",
"name": "_update",
"type": "bool"
}
],
"name": "updateInstance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ITornadoInstance",
"name": "_tornado",
"type": "address"
},
{
"internalType": "bytes",
"name": "_proof",
"type": "bytes"
},
{
"internalType": "bytes32",
"name": "_root",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_nullifierHash",
"type": "bytes32"
},
{
"internalType": "address payable",
"name": "_recipient",
"type": "address"
},
{
"internalType": "address payable",
"name": "_relayer",
"type": "address"
},
{
"internalType": "uint256",
"name": "_fee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_refund",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IERC20",
"name": "_token",
"type": "address"
},
{
"internalType": "address payable",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_balance",
"type": "uint256"
}
],
"name": "rescueTokens",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

132
cli.js

@ -17,8 +17,9 @@ const websnarkUtils = require('websnark/src/utils')
const { toWei, fromWei, toBN, BN } = require('web3-utils')
const config = require('./config')
const program = require('commander')
const { GasPriceOracle } = require('gas-price-oracle')
let web3, tornado, circuit, proving_key, groth16, erc20, senderAccount, netId
let web3, tornado, mixerContract, tornadoInstance, circuit, proving_key, groth16, erc20, senderAccount, netId
let MERKLE_TREE_HEIGHT, ETH_AMOUNT, TOKEN_AMOUNT, PRIVATE_KEY
/** Whether we are in a browser or node.js */
@ -77,7 +78,7 @@ async function deposit({ currency, amount }) {
await printETHBalance({ address: senderAccount, name: 'Sender account' })
const value = isLocalRPC ? ETH_AMOUNT : fromDecimals({ amount, decimals: 18 })
console.log('Submitting deposit transaction')
await tornado.methods.deposit(toHex(deposit.commitment)).send({ value, from: senderAccount, gas: 2e6 })
await tornado.methods.deposit(tornadoInstance, toHex(deposit.commitment), []).send({ value, from: senderAccount, gas: 2e6 })
await printETHBalance({ address: tornado._address, name: 'Tornado' })
await printETHBalance({ address: senderAccount, name: 'Sender account' })
} else { // a token
@ -113,22 +114,26 @@ async function deposit({ currency, amount }) {
* @param deposit Deposit object
*/
async function generateMerkleProof(deposit) {
let leafIndex = -1
// Get all deposit events from smart contract and assemble merkle tree from them
console.log('Getting current state from tornado contract')
const events = await tornado.getPastEvents('Deposit', { fromBlock: 0, toBlock: 'latest' })
const events = await mixerContract.getPastEvents('Deposit', { fromBlock: 0, toBlock: 'latest' })
const leaves = events
.sort((a, b) => a.returnValues.leafIndex - b.returnValues.leafIndex) // Sort events in chronological order
.map(e => e.returnValues.commitment)
const tree = new merkleTree(MERKLE_TREE_HEIGHT, leaves)
.map((e) => {
const index = toBN(e.returnValues.leafIndex).toNumber()
// Find current commitment in the tree
const depositEvent = events.find(e => e.returnValues.commitment === toHex(deposit.commitment))
const leafIndex = depositEvent ? depositEvent.returnValues.leafIndex : -1
if (toBN(e.returnValues.commitment).eq(toBN(deposit.commitmentHex))) {
leafIndex = index
}
return e.returnValues.commitment.toString(10)
})
const tree = new merkleTree(MERKLE_TREE_HEIGHT, leaves)
// Validate that our data is correct
const root = await tree.root()
const isValidRoot = await tornado.methods.isKnownRoot(toHex(root)).call()
const isSpent = await tornado.methods.isSpent(toHex(deposit.nullifierHash)).call()
const isValidRoot = await mixerContract.methods.isKnownRoot(toHex(root)).call()
const isSpent = await mixerContract.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')
@ -199,28 +204,29 @@ async function withdraw({ deposit, currency, amount, recipient, relayerURL, refu
throw new Error('ENS name resolving is not supported. Please provide DNS name of the relayer. See instuctions in README.md')
}
const relayerStatus = await axios.get(relayerURL + '/status')
const { relayerAddress, netId, gasPrices, ethPrices, relayerServiceFee } = relayerStatus.data
const { rewardAccount, netId, ethPrices, tornadoServiceFee } = relayerStatus.data
assert(netId === await web3.eth.net.getId() || netId === '*', 'This relay is for different network')
console.log('Relay address: ', relayerAddress)
console.log('Relay address: ', rewardAccount)
const gasPrice = await fetchGasPrice()
const decimals = isLocalRPC ? 18 : config.deployments[`netId${netId}`][currency].decimals
const fee = calculateFee({ gasPrices, currency, amount, refund, ethPrices, relayerServiceFee, decimals })
const fee = calculateFee({ currency, gasPrice, amount, refund, ethPrices, relayerServiceFee: tornadoServiceFee, decimals })
if (fee.gt(fromDecimals({ amount, decimals }))) {
throw new Error('Too high refund')
}
const { proof, args } = await generateProof({ deposit, recipient, relayerAddress, fee, refund })
const { proof, args } = await generateProof({ deposit, recipient, relayerAddress: rewardAccount, fee, refund })
console.log('Sending withdraw transaction through relay')
try {
const relay = await axios.post(relayerURL + '/relay', { contract: tornado._address, proof, args })
if (netId === 1 || netId === 42) {
console.log(`Transaction submitted through the relay. View transaction on etherscan https://${getCurrentNetworkName()}etherscan.io/tx/${relay.data.txHash}`)
} else {
console.log(`Transaction submitted through the relay. The transaction hash is ${relay.data.txHash}`)
}
const response = await axios.post(relayerURL + '/v1/tornadoWithdraw', { contract: tornadoInstance, proof, args })
const receipt = await waitForTxReceipt({ txHash: relay.data.txHash })
console.log('Transaction mined in block', receipt.blockNumber)
const { id } = response.data
const result = await getStatus(id, relayerURL)
console.log('STATUS', result)
} catch (e) {
if (e.response) {
console.error(e.response.data.error)
@ -232,7 +238,7 @@ async function withdraw({ deposit, currency, amount, recipient, relayerURL, refu
const { proof, args } = await generateProof({ deposit, recipient, refund })
console.log('Submitting withdraw transaction')
await tornado.methods.withdraw(proof, ...args).send({ from: senderAccount, value: refund.toString(), gas: 1e6 })
await tornado.methods.withdraw(tornadoInstance, proof, ...args).send({ from: senderAccount, value: refund.toString(), gas: 1e6 })
.on('transactionHash', function (txHash) {
if (netId === 1 || netId === 42) {
console.log(`View transaction on etherscan https://${getCurrentNetworkName()}etherscan.io/tx/${txHash}`)
@ -246,6 +252,37 @@ async function withdraw({ deposit, currency, amount, recipient, relayerURL, refu
console.log('Done')
}
function getStatus (id, relayerURL) {
return new Promise((resolve) => {
async function getRelayerStatus() {
const responseStatus = await axios.get(relayerURL + '/v1/jobs/' + id)
if (responseStatus.status === 200) {
const { txHash, status, confirmations, failedReason } = responseStatus.data
console.log(`Current job status ${status}, confirmations: ${confirmations}`)
if (status === 'FAILED') {
throw new Error(status + ' failed reason:' + failedReason)
}
if (status === 'CONFIRMED') {
const receipt = await waitForTxReceipt({ txHash })
console.log(`Transaction submitted through the relay. View transaction on etherscan https://${getCurrentNetworkName()}etherscan.io/tx/${txHash}`)
console.log('Transaction mined in block', receipt.blockNumber)
resolve(status)
}
}
setTimeout(() => {
getRelayerStatus(id, relayerURL)
}, 3000)
}
getRelayerStatus()
})
}
function fromDecimals({ amount, decimals }) {
amount = amount.toString()
let ether = amount.toString()
@ -338,20 +375,40 @@ function getCurrentNetworkName() {
switch (netId) {
case 1:
return ''
case 5:
return 'goerli.'
case 42:
return 'kovan.'
}
}
function calculateFee({ gasPrices, currency, amount, refund, ethPrices, relayerServiceFee, decimals }) {
function gasPrices(value = 80) {
const tenPercent = (Number(value) * 5) / 100
const max = Math.max(tenPercent, 3)
const bumped = Math.floor(Number(value) + max)
return toHex(toWei(bumped.toString(), 'gwei'))
}
async function fetchGasPrice() {
try {
const oracle = new GasPriceOracle()
const gas = await oracle.gasPrices()
return gasPrices(gas.fast)
} catch (err) {
throw new Error(`Method fetchGasPrice has error ${err.message}`)
}
}
function calculateFee({ currency, gasPrice, amount, refund, ethPrices, relayerServiceFee, decimals }) {
const decimalsPoint = Math.floor(relayerServiceFee) === Number(relayerServiceFee) ?
0 :
relayerServiceFee.toString().split('.')[1].length
const roundDecimal = 10 ** decimalsPoint
const total = toBN(fromDecimals({ amount, decimals }))
const feePercent = total.mul(toBN(relayerServiceFee * roundDecimal)).div(toBN(roundDecimal * 100))
const expense = toBN(toWei(gasPrices.fast.toString(), 'gwei')).mul(toBN(5e5))
const expense = toBN(gasPrice).mul(toBN(5e5))
let desiredFee
switch (currency) {
case 'eth': {
@ -471,15 +528,16 @@ async function loadWithdrawalData({ amount, currency, deposit }) {
* Init web3, contracts, and snark
*/
async function init({ rpc, noteNetId, currency = 'dai', amount = '100' }) {
let contractJson, erc20ContractJson, erc20tornadoJson, tornadoAddress, tokenAddress
let contractJson, mixerJson, erc20ContractJson, erc20tornadoJson, tornadoAddress, tokenAddress
// TODO do we need this? should it work in browser really?
if (inBrowser) {
// Initialize using injected web3 (Metamask)
// To assemble web version run `npm run browserify`
web3 = new Web3(window.web3.currentProvider, null, { transactionConfirmationBlocks: 1 })
contractJson = await (await fetch('build/contracts/ETHTornado.json')).json()
circuit = await (await fetch('build/circuits/withdraw.json')).json()
proving_key = await (await fetch('build/circuits/withdraw_proving_key.bin')).arrayBuffer()
contractJson = await (await fetch('build/contracts/TornadoProxy.abi.json')).json()
mixerJson = await (await fetch('build/contracts/Mixer.abi.json')).json()
circuit = await (await fetch('build/circuits/tornado.json')).json()
proving_key = await (await fetch('build/circuits/tornadoProvingKey.bin')).arrayBuffer()
MERKLE_TREE_HEIGHT = 20
ETH_AMOUNT = 1e18
TOKEN_AMOUNT = 1e19
@ -487,9 +545,10 @@ async function init({ rpc, noteNetId, currency = 'dai', amount = '100' }) {
} else {
// Initialize from local node
web3 = new Web3(rpc, null, { transactionConfirmationBlocks: 1 })
contractJson = require('./build/contracts/ETHTornado.json')
circuit = require('./build/circuits/withdraw.json')
proving_key = fs.readFileSync('build/circuits/withdraw_proving_key.bin').buffer
contractJson = require('./build/contracts/TornadoProxy.abi.json')
mixerJson = require('./build/contracts/Mixer.abi.json')
circuit = require('./build/circuits/tornado.json')
proving_key = fs.readFileSync('build/circuits/tornadoProvingKey.bin').buffer
MERKLE_TREE_HEIGHT = process.env.MERKLE_TREE_HEIGHT || 20
ETH_AMOUNT = process.env.ETH_AMOUNT
TOKEN_AMOUNT = process.env.TOKEN_AMOUNT
@ -519,7 +578,9 @@ async function init({ rpc, noteNetId, currency = 'dai', amount = '100' }) {
senderAccount = (await web3.eth.getAccounts())[0]
} else {
try {
tornadoAddress = config.deployments[`netId${netId}`][currency].instanceAddress[amount]
tornadoAddress = config.deployments[`netId${netId}`].proxy
tornadoInstance = config.deployments[`netId${netId}`][currency].instanceAddress[amount]
if (!tornadoAddress) {
throw new Error()
}
@ -529,7 +590,8 @@ async function init({ rpc, noteNetId, currency = 'dai', amount = '100' }) {
process.exit(1)
}
}
tornado = new web3.eth.Contract(contractJson.abi, tornadoAddress)
tornado = new web3.eth.Contract(contractJson, tornadoAddress)
mixerContract = new web3.eth.Contract(mixerJson, tornadoInstance)
erc20 = currency !== 'eth' ? new web3.eth.Contract(erc20ContractJson.abi, tokenAddress) : {}
}

@ -67,7 +67,76 @@ module.exports = {
tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
symbol: 'USDT',
decimals: 6
}
},
proxy: '0x905b63Fff465B9fFBF41DeA908CEb12478ec7601',
},
netId5: {
eth: {
instanceAddress: {
'0.1': '0x6Bf694a291DF3FeC1f7e69701E3ab6c592435Ae7',
'1': '0x3aac1cC67c2ec5Db4eA850957b967Ba153aD6279',
'10': '0x723B78e67497E85279CB204544566F4dC5d2acA0',
'100': '0x0E3A09dDA6B20aFbB34aC7cD4A6881493f3E7bf7'
},
symbol: 'ETH',
decimals: 18
},
dai: {
instanceAddress: {
'100': '0xdf2d3cC5F361CF95b3f62c4bB66deFe3FDE47e3D',
'1000': '0xD96291dFa35d180a71964D0894a1Ae54247C4ccD',
'10000': '0xb192794f72EA45e33C3DF6fe212B9c18f6F45AE3',
'100000': undefined
},
tokenAddress: '0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa',
symbol: 'DAI',
decimals: 18
},
cdai: {
instanceAddress: {
'5000': '0x6Fc9386ABAf83147b3a89C36D422c625F44121C8',
'50000': '0x7182EA067e0f050997444FCb065985Fd677C16b6',
'500000': '0xC22ceFd90fbd1FdEeE554AE6Cc671179BC3b10Ae',
'5000000': undefined
},
tokenAddress: '0xe7bc397DBd069fC7d0109C0636d06888bb50668c',
symbol: 'cDAI',
decimals: 8
},
usdc: {
instanceAddress: {
'100': '0x137E2B6d185018e7f09f6cf175a970e7fC73826C',
'1000': '0xcC7f1633A5068E86E3830e692e3e3f8f520525Af',
'10000': '0x28C8f149a0ab8A9bdB006B8F984fFFCCE52ef5EF',
'100000': undefined
},
tokenAddress: '0x75B0622Cec14130172EaE9Cf166B92E5C112FaFF',
symbol: 'USDC',
decimals: 6
},
cusdc: {
instanceAddress: {
'5000': '0xc0648F28ABA385c8a1421Bbf1B59e3c474F89cB0',
'50000': '0x0C53853379c6b1A7B74E0A324AcbDD5Eabd4981D',
'500000': '0xf84016A0E03917cBe700D318EB1b7a53e6e3dEe1',
'5000000': undefined
},
tokenAddress: '0xcfC9bB230F00bFFDB560fCe2428b4E05F3442E35',
symbol: 'cUSDC',
decimals: 8
},
usdt: {
instanceAddress: {
'100': '0x327853Da7916a6A0935563FB1919A48843036b42',
'1000': '0x531AA4DF5858EA1d0031Dad16e3274609DE5AcC0',
'10000': '0x0958275F0362cf6f07D21373aEE0cf37dFe415dD',
'100000': '0x14aEd24B67EaF3FF28503eB92aeb217C47514364'
},
tokenAddress: '0x03c5F29e9296006876d8DF210BCFfD7EA5Db1Cf1',
symbol: 'USDT',
decimals: 6
},
proxy: '0x905b63Fff465B9fFBF41DeA908CEb12478ec7601',
},
netId42: {
eth: {
@ -134,7 +203,8 @@ module.exports = {
tokenAddress: '0x03c5F29e9296006876d8DF210BCFfD7EA5Db1Cf1',
symbol: 'USDT',
decimals: 6
}
},
proxy: '0x26Dd6E44a7090a2598e280CBD1F5E6034F2edD04',
}
}
}

@ -11,9 +11,10 @@
"dependencies": {
"axios": "^0.19.2",
"circom": "0.0.35",
"circomlib": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc",
"circomlib": "git+https://github.com/tornadocash/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
"commander": "^5.1.0",
"dotenv": "^8.2.0",
"gas-price-oracle": "^0.2.2",
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
"web3": "^1.2.8",
"websnark": "git+https://github.com/tornadocash/websnark.git#4c0af6a8b65aabea3c09f377f63c44e7a58afa6d"

4122
yarn.lock Normal file

File diff suppressed because it is too large Load Diff