mirror of
https://github.com/tornadocash/tornado-core.git
synced 2024-12-18 07:13:29 +01:00
lint
This commit is contained in:
parent
c6b442713a
commit
346ffcee3c
27
.eslintrc
Normal file
27
.eslintrc
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"node": true,
|
||||||
|
"browser": true,
|
||||||
|
"es6": true,
|
||||||
|
"mocha": true
|
||||||
|
},
|
||||||
|
"extends": ["eslint:recommended", "plugin:prettier/recommended", "prettier"],
|
||||||
|
"globals": {
|
||||||
|
"Atomics": "readonly",
|
||||||
|
"SharedArrayBuffer": "readonly"
|
||||||
|
},
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2018
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": ["error", 2],
|
||||||
|
"linebreak-style": ["error", "unix"],
|
||||||
|
"quotes": ["error", "single"],
|
||||||
|
"semi": ["error", "never"],
|
||||||
|
"object-curly-spacing": ["error", "always"],
|
||||||
|
"comma-dangle": ["error", "always-multiline"],
|
||||||
|
"require-await": "error",
|
||||||
|
"prettier/prettier": ["error", { "printWidth": 110 }]
|
||||||
|
}
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
"browser": true,
|
|
||||||
"es6": true,
|
|
||||||
"mocha": true
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"globals": {
|
|
||||||
"Atomics": "readonly",
|
|
||||||
"SharedArrayBuffer": "readonly"
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2018
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"indent": [
|
|
||||||
"error",
|
|
||||||
2
|
|
||||||
],
|
|
||||||
"linebreak-style": [
|
|
||||||
"error",
|
|
||||||
"unix"
|
|
||||||
],
|
|
||||||
"quotes": [
|
|
||||||
"error",
|
|
||||||
"single"
|
|
||||||
],
|
|
||||||
"semi": [
|
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"object-curly-spacing": [
|
|
||||||
"error",
|
|
||||||
"always"
|
|
||||||
],
|
|
||||||
"require-await": "error"
|
|
||||||
}
|
|
||||||
}
|
|
6
.prettierignore
Normal file
6
.prettierignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.vscode
|
||||||
|
build
|
||||||
|
circuits
|
||||||
|
contracts/Verifier.sol
|
||||||
|
lib/ganacheHelper.js
|
||||||
|
cli.js
|
16
.prettierrc
Normal file
16
.prettierrc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"semi": false,
|
||||||
|
"printWidth": 110,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.sol",
|
||||||
|
"options": {
|
||||||
|
"singleQuote": false,
|
||||||
|
"printWidth": 130
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,6 +1,13 @@
|
|||||||
{
|
{
|
||||||
"extends": "solhint:recommended",
|
"extends": "solhint:recommended",
|
||||||
"rules": {
|
"rules": {
|
||||||
"indent": ["error", 2]
|
"prettier/prettier": [
|
||||||
}
|
"error",
|
||||||
|
{
|
||||||
|
"printWidth": 110
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quotes": ["error", "double"]
|
||||||
|
},
|
||||||
|
"plugins": ["prettier"]
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
dist: trusty
|
dist: trusty
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "11"
|
- '11'
|
||||||
install:
|
install:
|
||||||
- npm ci
|
- npm ci
|
||||||
- cp .env.example .env
|
- cp .env.example .env
|
||||||
|
16
cli.js
16
cli.js
@ -178,7 +178,7 @@ async function generateProof({ deposit, recipient, relayerAddress = 0, fee = 0,
|
|||||||
toHex(input.recipient, 20),
|
toHex(input.recipient, 20),
|
||||||
toHex(input.relayer, 20),
|
toHex(input.relayer, 20),
|
||||||
toHex(input.fee),
|
toHex(input.fee),
|
||||||
toHex(input.refund)
|
toHex(input.refund),
|
||||||
]
|
]
|
||||||
|
|
||||||
return { proof, args }
|
return { proof, args }
|
||||||
@ -265,7 +265,7 @@ function fromDecimals({ amount, decimals }) {
|
|||||||
const comps = ether.split('.')
|
const comps = ether.split('.')
|
||||||
if (comps.length > 2) {
|
if (comps.length > 2) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'[ethjs-unit] while converting number ' + amount + ' to wei, too many decimal points'
|
'[ethjs-unit] while converting number ' + amount + ' to wei, too many decimal points',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ function fromDecimals({ amount, decimals }) {
|
|||||||
}
|
}
|
||||||
if (fraction.length > baseLength) {
|
if (fraction.length > baseLength) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'[ethjs-unit] while converting number ' + amount + ' to wei, too many decimal places'
|
'[ethjs-unit] while converting number ' + amount + ' to wei, too many decimal places',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,10 +417,10 @@ async function loadDepositData({ deposit }) {
|
|||||||
try {
|
try {
|
||||||
const eventWhenHappened = await tornado.getPastEvents('Deposit', {
|
const eventWhenHappened = await tornado.getPastEvents('Deposit', {
|
||||||
filter: {
|
filter: {
|
||||||
commitment: deposit.commitmentHex
|
commitment: deposit.commitmentHex,
|
||||||
},
|
},
|
||||||
fromBlock: 0,
|
fromBlock: 0,
|
||||||
toBlock: 'latest'
|
toBlock: 'latest',
|
||||||
})
|
})
|
||||||
if (eventWhenHappened.length === 0) {
|
if (eventWhenHappened.length === 0) {
|
||||||
throw new Error('There is no related deposit, the note is invalid')
|
throw new Error('There is no related deposit, the note is invalid')
|
||||||
@ -441,7 +441,7 @@ async function loadWithdrawalData({ amount, currency, deposit }) {
|
|||||||
try {
|
try {
|
||||||
const events = await await tornado.getPastEvents('Withdrawal', {
|
const events = await await tornado.getPastEvents('Withdrawal', {
|
||||||
fromBlock: 0,
|
fromBlock: 0,
|
||||||
toBlock: 'latest'
|
toBlock: 'latest',
|
||||||
})
|
})
|
||||||
|
|
||||||
const withdrawEvent = events.filter((event) => {
|
const withdrawEvent = events.filter((event) => {
|
||||||
@ -451,7 +451,7 @@ async function loadWithdrawalData({ amount, currency, deposit }) {
|
|||||||
const fee = withdrawEvent.returnValues.fee
|
const fee = withdrawEvent.returnValues.fee
|
||||||
const decimals = config.deployments[`netId${netId}`][currency].decimals
|
const decimals = config.deployments[`netId${netId}`][currency].decimals
|
||||||
const withdrawalAmount = toBN(fromDecimals({ amount, decimals })).sub(
|
const withdrawalAmount = toBN(fromDecimals({ amount, decimals })).sub(
|
||||||
toBN(fee)
|
toBN(fee),
|
||||||
)
|
)
|
||||||
const { timestamp } = await web3.eth.getBlock(withdrawEvent.blockHash)
|
const { timestamp } = await web3.eth.getBlock(withdrawEvent.blockHash)
|
||||||
return {
|
return {
|
||||||
@ -460,7 +460,7 @@ async function loadWithdrawalData({ amount, currency, deposit }) {
|
|||||||
to: withdrawEvent.returnValues.to,
|
to: withdrawEvent.returnValues.to,
|
||||||
timestamp,
|
timestamp,
|
||||||
nullifier: deposit.nullifierHex,
|
nullifier: deposit.nullifierHex,
|
||||||
fee: toDecimals(fee, decimals, 9)
|
fee: toDecimals(fee, decimals, 9),
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('loadWithdrawalData', e)
|
console.error('loadWithdrawalData', e)
|
||||||
|
@ -8,11 +8,11 @@ const genContract = require('circomlib/src/mimcsponge_gencontract.js')
|
|||||||
// command
|
// command
|
||||||
const outputPath = path.join(__dirname, 'build', 'Hasher.json')
|
const outputPath = path.join(__dirname, 'build', 'Hasher.json')
|
||||||
|
|
||||||
function main () {
|
function main() {
|
||||||
const contract = {
|
const contract = {
|
||||||
contractName: 'Hasher',
|
contractName: 'Hasher',
|
||||||
abi: genContract.abi,
|
abi: genContract.abi,
|
||||||
bytecode: genContract.createCode('mimcsponge', 220)
|
bytecode: genContract.createCode('mimcsponge', 220),
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(outputPath, JSON.stringify(contract))
|
fs.writeFileSync(outputPath, JSON.stringify(contract))
|
||||||
|
128
config.js
128
config.js
@ -5,136 +5,136 @@ module.exports = {
|
|||||||
netId1: {
|
netId1: {
|
||||||
eth: {
|
eth: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'0.1': '0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc',
|
0.1: '0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc',
|
||||||
'1': '0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936',
|
1: '0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936',
|
||||||
'10': '0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF',
|
10: '0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF',
|
||||||
'100': '0xA160cdAB225685dA1d56aa342Ad8841c3b53f291'
|
100: '0xA160cdAB225685dA1d56aa342Ad8841c3b53f291',
|
||||||
},
|
},
|
||||||
symbol: 'ETH',
|
symbol: 'ETH',
|
||||||
decimals: 18
|
decimals: 18,
|
||||||
},
|
},
|
||||||
dai: {
|
dai: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'100': '0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3',
|
100: '0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3',
|
||||||
'1000': '0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144',
|
1000: '0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144',
|
||||||
'10000': '0xF60dD140cFf0706bAE9Cd734Ac3ae76AD9eBC32A',
|
10000: '0xF60dD140cFf0706bAE9Cd734Ac3ae76AD9eBC32A',
|
||||||
'100000': undefined
|
100000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
||||||
symbol: 'DAI',
|
symbol: 'DAI',
|
||||||
decimals: 18
|
decimals: 18,
|
||||||
},
|
},
|
||||||
cdai: {
|
cdai: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'5000': '0x22aaA7720ddd5388A3c0A3333430953C68f1849b',
|
5000: '0x22aaA7720ddd5388A3c0A3333430953C68f1849b',
|
||||||
'50000': '0xBA214C1c1928a32Bffe790263E38B4Af9bFCD659',
|
50000: '0xBA214C1c1928a32Bffe790263E38B4Af9bFCD659',
|
||||||
'500000': '0xb1C8094B234DcE6e03f10a5b673c1d8C69739A00',
|
500000: '0xb1C8094B234DcE6e03f10a5b673c1d8C69739A00',
|
||||||
'5000000': undefined
|
5000000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643',
|
tokenAddress: '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643',
|
||||||
symbol: 'cDAI',
|
symbol: 'cDAI',
|
||||||
decimals: 8
|
decimals: 8,
|
||||||
},
|
},
|
||||||
usdc: {
|
usdc: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'100': '0xd96f2B1c14Db8458374d9Aca76E26c3D18364307',
|
100: '0xd96f2B1c14Db8458374d9Aca76E26c3D18364307',
|
||||||
'1000': '0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D',
|
1000: '0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D',
|
||||||
'10000': '0xD691F27f38B395864Ea86CfC7253969B409c362d',
|
10000: '0xD691F27f38B395864Ea86CfC7253969B409c362d',
|
||||||
'100000': undefined
|
100000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
||||||
symbol: 'USDC',
|
symbol: 'USDC',
|
||||||
decimals: 6
|
decimals: 6,
|
||||||
},
|
},
|
||||||
cusdc: {
|
cusdc: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'5000': '0xaEaaC358560e11f52454D997AAFF2c5731B6f8a6',
|
5000: '0xaEaaC358560e11f52454D997AAFF2c5731B6f8a6',
|
||||||
'50000': '0x1356c899D8C9467C7f71C195612F8A395aBf2f0a',
|
50000: '0x1356c899D8C9467C7f71C195612F8A395aBf2f0a',
|
||||||
'500000': '0xA60C772958a3eD56c1F15dD055bA37AC8e523a0D',
|
500000: '0xA60C772958a3eD56c1F15dD055bA37AC8e523a0D',
|
||||||
'5000000': undefined
|
5000000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0x39AA39c021dfbaE8faC545936693aC917d5E7563',
|
tokenAddress: '0x39AA39c021dfbaE8faC545936693aC917d5E7563',
|
||||||
symbol: 'cUSDC',
|
symbol: 'cUSDC',
|
||||||
decimals: 8
|
decimals: 8,
|
||||||
},
|
},
|
||||||
usdt: {
|
usdt: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'100': '0x169AD27A470D064DEDE56a2D3ff727986b15D52B',
|
100: '0x169AD27A470D064DEDE56a2D3ff727986b15D52B',
|
||||||
'1000': '0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f',
|
1000: '0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f',
|
||||||
'10000': '0xF67721A2D8F736E75a49FdD7FAd2e31D8676542a',
|
10000: '0xF67721A2D8F736E75a49FdD7FAd2e31D8676542a',
|
||||||
'100000': '0x9AD122c22B14202B4490eDAf288FDb3C7cb3ff5E'
|
100000: '0x9AD122c22B14202B4490eDAf288FDb3C7cb3ff5E',
|
||||||
},
|
},
|
||||||
tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
||||||
symbol: 'USDT',
|
symbol: 'USDT',
|
||||||
decimals: 6
|
decimals: 6,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
netId42: {
|
netId42: {
|
||||||
eth: {
|
eth: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'0.1': '0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f',
|
0.1: '0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f',
|
||||||
'1': '0xD6a6AC46d02253c938B96D12BE439F570227aE8E',
|
1: '0xD6a6AC46d02253c938B96D12BE439F570227aE8E',
|
||||||
'10': '0xe1BE96331391E519471100c3c1528B66B8F4e5a7',
|
10: '0xe1BE96331391E519471100c3c1528B66B8F4e5a7',
|
||||||
'100': '0xd037E0Ac98Dab2fCb7E296c69C6e52767Ae5414D'
|
100: '0xd037E0Ac98Dab2fCb7E296c69C6e52767Ae5414D',
|
||||||
},
|
},
|
||||||
symbol: 'ETH',
|
symbol: 'ETH',
|
||||||
decimals: 18
|
decimals: 18,
|
||||||
},
|
},
|
||||||
dai: {
|
dai: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'100': '0xdf2d3cC5F361CF95b3f62c4bB66deFe3FDE47e3D',
|
100: '0xdf2d3cC5F361CF95b3f62c4bB66deFe3FDE47e3D',
|
||||||
'1000': '0xD96291dFa35d180a71964D0894a1Ae54247C4ccD',
|
1000: '0xD96291dFa35d180a71964D0894a1Ae54247C4ccD',
|
||||||
'10000': '0xb192794f72EA45e33C3DF6fe212B9c18f6F45AE3',
|
10000: '0xb192794f72EA45e33C3DF6fe212B9c18f6F45AE3',
|
||||||
'100000': undefined
|
100000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa',
|
tokenAddress: '0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa',
|
||||||
symbol: 'DAI',
|
symbol: 'DAI',
|
||||||
decimals: 18
|
decimals: 18,
|
||||||
},
|
},
|
||||||
cdai: {
|
cdai: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'5000': '0x6Fc9386ABAf83147b3a89C36D422c625F44121C8',
|
5000: '0x6Fc9386ABAf83147b3a89C36D422c625F44121C8',
|
||||||
'50000': '0x7182EA067e0f050997444FCb065985Fd677C16b6',
|
50000: '0x7182EA067e0f050997444FCb065985Fd677C16b6',
|
||||||
'500000': '0xC22ceFd90fbd1FdEeE554AE6Cc671179BC3b10Ae',
|
500000: '0xC22ceFd90fbd1FdEeE554AE6Cc671179BC3b10Ae',
|
||||||
'5000000': undefined
|
5000000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0xe7bc397DBd069fC7d0109C0636d06888bb50668c',
|
tokenAddress: '0xe7bc397DBd069fC7d0109C0636d06888bb50668c',
|
||||||
symbol: 'cDAI',
|
symbol: 'cDAI',
|
||||||
decimals: 8
|
decimals: 8,
|
||||||
},
|
},
|
||||||
usdc: {
|
usdc: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'100': '0x137E2B6d185018e7f09f6cf175a970e7fC73826C',
|
100: '0x137E2B6d185018e7f09f6cf175a970e7fC73826C',
|
||||||
'1000': '0xcC7f1633A5068E86E3830e692e3e3f8f520525Af',
|
1000: '0xcC7f1633A5068E86E3830e692e3e3f8f520525Af',
|
||||||
'10000': '0x28C8f149a0ab8A9bdB006B8F984fFFCCE52ef5EF',
|
10000: '0x28C8f149a0ab8A9bdB006B8F984fFFCCE52ef5EF',
|
||||||
'100000': undefined
|
100000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0x75B0622Cec14130172EaE9Cf166B92E5C112FaFF',
|
tokenAddress: '0x75B0622Cec14130172EaE9Cf166B92E5C112FaFF',
|
||||||
symbol: 'USDC',
|
symbol: 'USDC',
|
||||||
decimals: 6
|
decimals: 6,
|
||||||
},
|
},
|
||||||
cusdc: {
|
cusdc: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'5000': '0xc0648F28ABA385c8a1421Bbf1B59e3c474F89cB0',
|
5000: '0xc0648F28ABA385c8a1421Bbf1B59e3c474F89cB0',
|
||||||
'50000': '0x0C53853379c6b1A7B74E0A324AcbDD5Eabd4981D',
|
50000: '0x0C53853379c6b1A7B74E0A324AcbDD5Eabd4981D',
|
||||||
'500000': '0xf84016A0E03917cBe700D318EB1b7a53e6e3dEe1',
|
500000: '0xf84016A0E03917cBe700D318EB1b7a53e6e3dEe1',
|
||||||
'5000000': undefined
|
5000000: undefined,
|
||||||
},
|
},
|
||||||
tokenAddress: '0xcfC9bB230F00bFFDB560fCe2428b4E05F3442E35',
|
tokenAddress: '0xcfC9bB230F00bFFDB560fCe2428b4E05F3442E35',
|
||||||
symbol: 'cUSDC',
|
symbol: 'cUSDC',
|
||||||
decimals: 8
|
decimals: 8,
|
||||||
},
|
},
|
||||||
usdt: {
|
usdt: {
|
||||||
instanceAddress: {
|
instanceAddress: {
|
||||||
'100': '0x327853Da7916a6A0935563FB1919A48843036b42',
|
100: '0x327853Da7916a6A0935563FB1919A48843036b42',
|
||||||
'1000': '0x531AA4DF5858EA1d0031Dad16e3274609DE5AcC0',
|
1000: '0x531AA4DF5858EA1d0031Dad16e3274609DE5AcC0',
|
||||||
'10000': '0x0958275F0362cf6f07D21373aEE0cf37dFe415dD',
|
10000: '0x0958275F0362cf6f07D21373aEE0cf37dFe415dD',
|
||||||
'100000': '0x14aEd24B67EaF3FF28503eB92aeb217C47514364'
|
100000: '0x14aEd24B67EaF3FF28503eB92aeb217C47514364',
|
||||||
},
|
},
|
||||||
tokenAddress: '0x03c5F29e9296006876d8DF210BCFfD7EA5Db1Cf1',
|
tokenAddress: '0x03c5F29e9296006876d8DF210BCFfD7EA5Db1Cf1',
|
||||||
symbol: 'USDT',
|
symbol: 'USDT',
|
||||||
decimals: 6
|
decimals: 6,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// https://tornado.cash
|
// https://tornado.cash
|
||||||
/*
|
/*
|
||||||
* d888888P dP a88888b. dP
|
* d888888P dP a88888b. dP
|
||||||
* 88 88 d8' `88 88
|
* 88 88 d8' `88 88
|
||||||
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
||||||
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
||||||
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
||||||
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
||||||
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
pragma solidity ^0.6.0;
|
pragma solidity ^0.6.0;
|
||||||
@ -23,7 +23,7 @@ contract ERC20Tornado is Tornado {
|
|||||||
uint256 _denomination,
|
uint256 _denomination,
|
||||||
uint32 _merkleTreeHeight,
|
uint32 _merkleTreeHeight,
|
||||||
address _token
|
address _token
|
||||||
) Tornado(_verifier, _hasher, _denomination, _merkleTreeHeight) public {
|
) public Tornado(_verifier, _hasher, _denomination, _merkleTreeHeight) {
|
||||||
token = _token;
|
token = _token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,12 @@ contract ERC20Tornado is Tornado {
|
|||||||
_safeErc20TransferFrom(msg.sender, address(this), denomination);
|
_safeErc20TransferFrom(msg.sender, address(this), denomination);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _processWithdraw(address payable _recipient, address payable _relayer, uint256 _fee, uint256 _refund) internal override {
|
function _processWithdraw(
|
||||||
|
address payable _recipient,
|
||||||
|
address payable _relayer,
|
||||||
|
uint256 _fee,
|
||||||
|
uint256 _refund
|
||||||
|
) internal override {
|
||||||
require(msg.value == _refund, "Incorrect refund amount received by the contract");
|
require(msg.value == _refund, "Incorrect refund amount received by the contract");
|
||||||
|
|
||||||
_safeErc20Transfer(_recipient, denomination - _fee);
|
_safeErc20Transfer(_recipient, denomination - _fee);
|
||||||
@ -49,8 +54,20 @@ contract ERC20Tornado is Tornado {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _safeErc20TransferFrom(address _from, address _to, uint256 _amount) internal {
|
function _safeErc20TransferFrom(
|
||||||
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd /* transferFrom */, _from, _to, _amount));
|
address _from,
|
||||||
|
address _to,
|
||||||
|
uint256 _amount
|
||||||
|
) internal {
|
||||||
|
(bool success, bytes memory data) =
|
||||||
|
token.call(
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
0x23b872dd, /* transferFrom */
|
||||||
|
_from,
|
||||||
|
_to,
|
||||||
|
_amount
|
||||||
|
)
|
||||||
|
);
|
||||||
require(success, "not enough allowed tokens");
|
require(success, "not enough allowed tokens");
|
||||||
|
|
||||||
// if contract returns some data lets make sure that is `true` according to standard
|
// if contract returns some data lets make sure that is `true` according to standard
|
||||||
@ -62,7 +79,14 @@ contract ERC20Tornado is Tornado {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _safeErc20Transfer(address _to, uint256 _amount) internal {
|
function _safeErc20Transfer(address _to, uint256 _amount) internal {
|
||||||
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb /* transfer */, _to, _amount));
|
(bool success, bytes memory data) =
|
||||||
|
token.call(
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
0xa9059cbb, /* transfer */
|
||||||
|
_to,
|
||||||
|
_amount
|
||||||
|
)
|
||||||
|
);
|
||||||
require(success, "not enough tokens");
|
require(success, "not enough tokens");
|
||||||
|
|
||||||
// if contract returns some data lets make sure that is `true` according to standard
|
// if contract returns some data lets make sure that is `true` according to standard
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// https://tornado.cash
|
// https://tornado.cash
|
||||||
/*
|
/*
|
||||||
* d888888P dP a88888b. dP
|
* d888888P dP a88888b. dP
|
||||||
* 88 88 d8' `88 88
|
* 88 88 d8' `88 88
|
||||||
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
||||||
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
||||||
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
||||||
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
||||||
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
pragma solidity ^0.6.0;
|
pragma solidity ^0.6.0;
|
||||||
@ -20,14 +20,18 @@ contract ETHTornado is Tornado {
|
|||||||
Hasher _hasher,
|
Hasher _hasher,
|
||||||
uint256 _denomination,
|
uint256 _denomination,
|
||||||
uint32 _merkleTreeHeight
|
uint32 _merkleTreeHeight
|
||||||
) Tornado(_verifier, _hasher, _denomination, _merkleTreeHeight) public {
|
) public Tornado(_verifier, _hasher, _denomination, _merkleTreeHeight) {}
|
||||||
}
|
|
||||||
|
|
||||||
function _processDeposit() internal override {
|
function _processDeposit() internal override {
|
||||||
require(msg.value == denomination, "Please send `mixDenomination` ETH along with transaction");
|
require(msg.value == denomination, "Please send `mixDenomination` ETH along with transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
function _processWithdraw(address payable _recipient, address payable _relayer, uint256 _fee, uint256 _refund) internal override {
|
function _processWithdraw(
|
||||||
|
address payable _recipient,
|
||||||
|
address payable _relayer,
|
||||||
|
uint256 _fee,
|
||||||
|
uint256 _refund
|
||||||
|
) internal override {
|
||||||
// sanity checks
|
// sanity checks
|
||||||
require(msg.value == 0, "Message value is supposed to be zero for ETH instance");
|
require(msg.value == 0, "Message value is supposed to be zero for ETH instance");
|
||||||
require(_refund == 0, "Refund value is supposed to be zero for ETH instance");
|
require(_refund == 0, "Refund value is supposed to be zero for ETH instance");
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// https://tornado.cash
|
// https://tornado.cash
|
||||||
/*
|
/*
|
||||||
* d888888P dP a88888b. dP
|
* d888888P dP a88888b. dP
|
||||||
* 88 88 d8' `88 88
|
* 88 88 d8' `88 88
|
||||||
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
||||||
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
||||||
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
||||||
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
||||||
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
pragma solidity ^0.6.0;
|
pragma solidity ^0.6.0;
|
||||||
@ -55,7 +55,11 @@ contract MerkleTreeWithHistory {
|
|||||||
/**
|
/**
|
||||||
@dev Hash 2 tree leaves, returns MiMC(_left, _right)
|
@dev Hash 2 tree leaves, returns MiMC(_left, _right)
|
||||||
*/
|
*/
|
||||||
function hashLeftRight(Hasher _hasher, bytes32 _left, bytes32 _right) public pure returns (bytes32) {
|
function hashLeftRight(
|
||||||
|
Hasher _hasher,
|
||||||
|
bytes32 _left,
|
||||||
|
bytes32 _right
|
||||||
|
) public pure returns (bytes32) {
|
||||||
require(uint256(_left) < FIELD_SIZE, "_left should be inside the field");
|
require(uint256(_left) < FIELD_SIZE, "_left should be inside the field");
|
||||||
require(uint256(_right) < FIELD_SIZE, "_right should be inside the field");
|
require(uint256(_right) < FIELD_SIZE, "_right should be inside the field");
|
||||||
uint256 R = uint256(_left);
|
uint256 R = uint256(_left);
|
||||||
@ -66,7 +70,7 @@ contract MerkleTreeWithHistory {
|
|||||||
return bytes32(R);
|
return bytes32(R);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _insert(bytes32 _leaf) internal returns(uint32 index) {
|
function _insert(bytes32 _leaf) internal returns (uint32 index) {
|
||||||
uint32 currentIndex = nextIndex;
|
uint32 currentIndex = nextIndex;
|
||||||
require(currentIndex != uint32(2)**levels, "Merkle tree is full. No more leafs can be added");
|
require(currentIndex != uint32(2)**levels, "Merkle tree is full. No more leafs can be added");
|
||||||
nextIndex += 1;
|
nextIndex += 1;
|
||||||
@ -98,7 +102,7 @@ contract MerkleTreeWithHistory {
|
|||||||
/**
|
/**
|
||||||
@dev Whether the root is present in the root history
|
@dev Whether the root is present in the root history
|
||||||
*/
|
*/
|
||||||
function isKnownRoot(bytes32 _root) public view returns(bool) {
|
function isKnownRoot(bytes32 _root) public view returns (bool) {
|
||||||
if (_root == 0) {
|
if (_root == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -118,7 +122,7 @@ contract MerkleTreeWithHistory {
|
|||||||
/**
|
/**
|
||||||
@dev Returns the last root
|
@dev Returns the last root
|
||||||
*/
|
*/
|
||||||
function getLastRoot() public view returns(bytes32) {
|
function getLastRoot() public view returns (bytes32) {
|
||||||
return roots[currentRootIndex];
|
return roots[currentRootIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,4 @@ pragma solidity ^0.6.0;
|
|||||||
|
|
||||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||||
|
|
||||||
contract ERC20Mock is ERC20 {
|
contract ERC20Mock is ERC20("DAIMock", "DAIM") {}
|
||||||
constructor() ERC20("DAIMock", "DAIM") public {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,11 +3,15 @@
|
|||||||
pragma solidity ^0.6.0;
|
pragma solidity ^0.6.0;
|
||||||
|
|
||||||
interface ERC20Basic {
|
interface ERC20Basic {
|
||||||
function _totalSupply() external returns(uint);
|
function _totalSupply() external returns (uint256);
|
||||||
function totalSupply() external view returns (uint);
|
|
||||||
function balanceOf(address who) external view returns (uint);
|
function totalSupply() external view returns (uint256);
|
||||||
function transfer(address to, uint value) external;
|
|
||||||
event Transfer(address indexed from, address indexed to, uint value);
|
function balanceOf(address who) external view returns (uint256);
|
||||||
|
|
||||||
|
function transfer(address to, uint256 value) external;
|
||||||
|
|
||||||
|
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,8 +19,15 @@ interface ERC20Basic {
|
|||||||
* @dev see https://github.com/ethereum/EIPs/issues/20
|
* @dev see https://github.com/ethereum/EIPs/issues/20
|
||||||
*/
|
*/
|
||||||
interface IUSDT is ERC20Basic {
|
interface IUSDT is ERC20Basic {
|
||||||
function allowance(address owner, address spender) external view returns (uint);
|
function allowance(address owner, address spender) external view returns (uint256);
|
||||||
function transferFrom(address from, address to, uint value) external;
|
|
||||||
function approve(address spender, uint value) external;
|
function transferFrom(
|
||||||
event Approval(address indexed owner, address indexed spender, uint value);
|
address from,
|
||||||
|
address to,
|
||||||
|
uint256 value
|
||||||
|
) external;
|
||||||
|
|
||||||
|
function approve(address spender, uint256 value) external;
|
||||||
|
|
||||||
|
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
pragma solidity ^0.6.0;
|
pragma solidity ^0.6.0;
|
||||||
|
|
||||||
import '../MerkleTreeWithHistory.sol';
|
import "../MerkleTreeWithHistory.sol";
|
||||||
|
|
||||||
contract MerkleTreeWithHistoryMock is MerkleTreeWithHistory {
|
contract MerkleTreeWithHistoryMock is MerkleTreeWithHistory {
|
||||||
|
constructor(uint32 _treeLevels, Hasher _hasher) public MerkleTreeWithHistory(_treeLevels, _hasher) {}
|
||||||
constructor (uint32 _treeLevels, Hasher _hasher) MerkleTreeWithHistory(_treeLevels, _hasher) public {}
|
|
||||||
|
|
||||||
function insert(bytes32 _leaf) public {
|
function insert(bytes32 _leaf) public {
|
||||||
_insert(_leaf);
|
_insert(_leaf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// https://tornado.cash
|
// https://tornado.cash
|
||||||
/*
|
/*
|
||||||
* d888888P dP a88888b. dP
|
* d888888P dP a88888b. dP
|
||||||
* 88 88 d8' `88 88
|
* 88 88 d8' `88 88
|
||||||
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
||||||
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
||||||
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
||||||
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
||||||
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
pragma solidity ^0.6.0;
|
pragma solidity ^0.6.0;
|
||||||
@ -16,7 +16,7 @@ import "./MerkleTreeWithHistory.sol";
|
|||||||
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
|
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
|
||||||
|
|
||||||
interface IVerifier {
|
interface IVerifier {
|
||||||
function verifyProof(bytes memory _proof, uint256[6] memory _input) external returns(bool);
|
function verifyProof(bytes memory _proof, uint256[6] memory _input) external returns (bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract contract Tornado is MerkleTreeWithHistory, ReentrancyGuard {
|
abstract contract Tornado is MerkleTreeWithHistory, ReentrancyGuard {
|
||||||
@ -49,7 +49,7 @@ abstract contract Tornado is MerkleTreeWithHistory, ReentrancyGuard {
|
|||||||
Hasher _hasher,
|
Hasher _hasher,
|
||||||
uint256 _denomination,
|
uint256 _denomination,
|
||||||
uint32 _merkleTreeHeight
|
uint32 _merkleTreeHeight
|
||||||
) MerkleTreeWithHistory(_merkleTreeHeight, _hasher) public {
|
) public MerkleTreeWithHistory(_merkleTreeHeight, _hasher) {
|
||||||
require(_denomination > 0, "denomination should be greater than 0");
|
require(_denomination > 0, "denomination should be greater than 0");
|
||||||
verifier = _verifier;
|
verifier = _verifier;
|
||||||
denomination = _denomination;
|
denomination = _denomination;
|
||||||
@ -80,11 +80,25 @@ abstract contract Tornado is MerkleTreeWithHistory, ReentrancyGuard {
|
|||||||
- the recipient of funds
|
- the recipient of funds
|
||||||
- optional fee that goes to the transaction sender (usually a relay)
|
- optional fee that goes to the transaction sender (usually a relay)
|
||||||
*/
|
*/
|
||||||
function withdraw(bytes calldata _proof, bytes32 _root, bytes32 _nullifierHash, address payable _recipient, address payable _relayer, uint256 _fee, uint256 _refund) external payable nonReentrant {
|
function withdraw(
|
||||||
|
bytes calldata _proof,
|
||||||
|
bytes32 _root,
|
||||||
|
bytes32 _nullifierHash,
|
||||||
|
address payable _recipient,
|
||||||
|
address payable _relayer,
|
||||||
|
uint256 _fee,
|
||||||
|
uint256 _refund
|
||||||
|
) external payable nonReentrant {
|
||||||
require(_fee <= denomination, "Fee exceeds transfer value");
|
require(_fee <= denomination, "Fee exceeds transfer value");
|
||||||
require(!nullifierHashes[_nullifierHash], "The note has been already spent");
|
require(!nullifierHashes[_nullifierHash], "The note has been already spent");
|
||||||
require(isKnownRoot(_root), "Cannot find your merkle root"); // Make sure to use a recent one
|
require(isKnownRoot(_root), "Cannot find your merkle root"); // Make sure to use a recent one
|
||||||
require(verifier.verifyProof(_proof, [uint256(_root), uint256(_nullifierHash), uint256(_recipient), uint256(_relayer), _fee, _refund]), "Invalid withdraw proof");
|
require(
|
||||||
|
verifier.verifyProof(
|
||||||
|
_proof,
|
||||||
|
[uint256(_root), uint256(_nullifierHash), uint256(_recipient), uint256(_relayer), _fee, _refund]
|
||||||
|
),
|
||||||
|
"Invalid withdraw proof"
|
||||||
|
);
|
||||||
|
|
||||||
nullifierHashes[_nullifierHash] = true;
|
nullifierHashes[_nullifierHash] = true;
|
||||||
_processWithdraw(_recipient, _relayer, _fee, _refund);
|
_processWithdraw(_recipient, _relayer, _fee, _refund);
|
||||||
@ -92,21 +106,25 @@ abstract contract Tornado is MerkleTreeWithHistory, ReentrancyGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @dev this function is defined in a child contract */
|
/** @dev this function is defined in a child contract */
|
||||||
function _processWithdraw(address payable _recipient, address payable _relayer, uint256 _fee, uint256 _refund) internal virtual;
|
function _processWithdraw(
|
||||||
|
address payable _recipient,
|
||||||
|
address payable _relayer,
|
||||||
|
uint256 _fee,
|
||||||
|
uint256 _refund
|
||||||
|
) internal virtual;
|
||||||
|
|
||||||
/** @dev whether a note is already spent */
|
/** @dev whether a note is already spent */
|
||||||
function isSpent(bytes32 _nullifierHash) public view returns(bool) {
|
function isSpent(bytes32 _nullifierHash) public view returns (bool) {
|
||||||
return nullifierHashes[_nullifierHash];
|
return nullifierHashes[_nullifierHash];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dev whether an array of notes is already spent */
|
/** @dev whether an array of notes is already spent */
|
||||||
function isSpentArray(bytes32[] calldata _nullifierHashes) external view returns(bool[] memory spent) {
|
function isSpentArray(bytes32[] calldata _nullifierHashes) external view returns (bool[] memory spent) {
|
||||||
spent = new bool[](_nullifierHashes.length);
|
spent = new bool[](_nullifierHashes.length);
|
||||||
for(uint i = 0; i < _nullifierHashes.length; i++) {
|
for (uint256 i = 0; i < _nullifierHashes.length; i++) {
|
||||||
if (isSpent(_nullifierHashes[i])) {
|
if (isSpent(_nullifierHashes[i])) {
|
||||||
spent[i] = true;
|
spent[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ async function downloadFile({ url, path }) {
|
|||||||
const response = await axios({
|
const response = await axios({
|
||||||
url,
|
url,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
responseType: 'stream'
|
responseType: 'stream',
|
||||||
})
|
})
|
||||||
|
|
||||||
response.data.pipe(writer)
|
response.data.pipe(writer)
|
||||||
@ -25,16 +25,16 @@ async function downloadFile({ url, path }) {
|
|||||||
async function main() {
|
async function main() {
|
||||||
const release = await axios.get('https://api.github.com/repos/tornadocash/tornado-core/releases/latest')
|
const release = await axios.get('https://api.github.com/repos/tornadocash/tornado-core/releases/latest')
|
||||||
const { assets } = release.data
|
const { assets } = release.data
|
||||||
if (!fs.existsSync(circuitsPath)){
|
if (!fs.existsSync(circuitsPath)) {
|
||||||
fs.mkdirSync(circuitsPath, { recursive: true })
|
fs.mkdirSync(circuitsPath, { recursive: true })
|
||||||
fs.mkdirSync(contractsPath, { recursive: true })
|
fs.mkdirSync(contractsPath, { recursive: true })
|
||||||
}
|
}
|
||||||
for(let asset of assets) {
|
for (let asset of assets) {
|
||||||
if (files.includes(asset.name)) {
|
if (files.includes(asset.name)) {
|
||||||
console.log(`Downloading ${asset.name} ...`)
|
console.log(`Downloading ${asset.name} ...`)
|
||||||
await downloadFile({
|
await downloadFile({
|
||||||
url: asset.browser_download_url,
|
url: asset.browser_download_url,
|
||||||
path: path.resolve(__dirname, circuitsPath, asset.name)
|
path: path.resolve(__dirname, circuitsPath, asset.name),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
index.html
29
index.html
@ -1,16 +1,17 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<title>Tornado test</title>
|
<title>Tornado test</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
Open dev console!<br>
|
Open dev console!<br />
|
||||||
Make sure your Metamask is unlocked and connected to Kovan (or other network you've deployed your contract to)<br>
|
Make sure your Metamask is unlocked and connected to Kovan (or other network you've deployed your
|
||||||
<a href="#" onclick="deposit()">Deposit</a>
|
contract to)<br />
|
||||||
<a href="#" onclick="withdraw()">Withdraw</a>
|
<a href="#" onclick="deposit()">Deposit</a>
|
||||||
</p>
|
<a href="#" onclick="withdraw()">Withdraw</a>
|
||||||
<script src="index.js"></script>
|
</p>
|
||||||
</body>
|
<script src="index.js"></script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -2,7 +2,6 @@ const jsStorage = require('./Storage')
|
|||||||
const hasherImpl = require('./MiMC')
|
const hasherImpl = require('./MiMC')
|
||||||
|
|
||||||
class MerkleTree {
|
class MerkleTree {
|
||||||
|
|
||||||
constructor(n_levels, defaultElements, prefix, storage, hasher) {
|
constructor(n_levels, defaultElements, prefix, storage, hasher) {
|
||||||
this.prefix = prefix
|
this.prefix = prefix
|
||||||
this.storage = storage || new jsStorage()
|
this.storage = storage || new jsStorage()
|
||||||
@ -15,9 +14,7 @@ class MerkleTree {
|
|||||||
this.zero_values.push(current_zero_value)
|
this.zero_values.push(current_zero_value)
|
||||||
for (let i = 0; i < n_levels; i++) {
|
for (let i = 0; i < n_levels; i++) {
|
||||||
current_zero_value = this.hasher.hash(i, current_zero_value, current_zero_value)
|
current_zero_value = this.hasher.hash(i, current_zero_value, current_zero_value)
|
||||||
this.zero_values.push(
|
this.zero_values.push(current_zero_value.toString())
|
||||||
current_zero_value.toString(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if (defaultElements) {
|
if (defaultElements) {
|
||||||
let level = 0
|
let level = 0
|
||||||
@ -28,7 +25,7 @@ class MerkleTree {
|
|||||||
level++
|
level++
|
||||||
let numberOfElementsInLevel = Math.ceil(defaultElements.length / 2)
|
let numberOfElementsInLevel = Math.ceil(defaultElements.length / 2)
|
||||||
for (level; level <= this.n_levels; level++) {
|
for (level; level <= this.n_levels; level++) {
|
||||||
for(let i = 0; i < numberOfElementsInLevel; i++) {
|
for (let i = 0; i < numberOfElementsInLevel; i++) {
|
||||||
const leftKey = MerkleTree.index_to_key(prefix, level - 1, 2 * 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 rightKey = MerkleTree.index_to_key(prefix, level - 1, 2 * i + 1)
|
||||||
|
|
||||||
@ -93,14 +90,14 @@ class MerkleTree {
|
|||||||
root,
|
root,
|
||||||
path_elements: traverser.path_elements,
|
path_elements: traverser.path_elements,
|
||||||
path_index: traverser.path_index,
|
path_index: traverser.path_index,
|
||||||
element
|
element,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(index, element, insert = false) {
|
async update(index, element, insert = false) {
|
||||||
if (!insert && index >= this.totalElements) {
|
if (!insert && index >= this.totalElements) {
|
||||||
throw Error('Use insert method for new elements.')
|
throw Error('Use insert method for new elements.')
|
||||||
} else if(insert && index < this.totalElements) {
|
} else if (insert && index < this.totalElements) {
|
||||||
throw Error('Use update method for existing elements.')
|
throw Error('Use update method for existing elements.')
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -141,13 +138,7 @@ class MerkleTree {
|
|||||||
this.current_element = this.hasher.hash(level, left, right)
|
this.current_element = this.hasher.hash(level, left, right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let traverser = new UpdateTraverser(
|
let traverser = new UpdateTraverser(this.prefix, this.storage, this.hasher, element, this.zero_values)
|
||||||
this.prefix,
|
|
||||||
this.storage,
|
|
||||||
this.hasher,
|
|
||||||
element,
|
|
||||||
this.zero_values
|
|
||||||
)
|
|
||||||
|
|
||||||
await this.traverse(index, traverser)
|
await this.traverse(index, traverser)
|
||||||
traverser.key_values_to_put.push({
|
traverser.key_values_to_put.push({
|
||||||
@ -156,7 +147,7 @@ class MerkleTree {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await this.storage.put_batch(traverser.key_values_to_put)
|
await this.storage.put_batch(traverser.key_values_to_put)
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +173,7 @@ class MerkleTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getIndexByElement(element) {
|
getIndexByElement(element) {
|
||||||
for(let i = this.totalElements - 1; i >= 0; i--) {
|
for (let i = this.totalElements - 1; i >= 0; i--) {
|
||||||
const elementFromTree = this.storage.get(MerkleTree.index_to_key(this.prefix, 0, i))
|
const elementFromTree = this.storage.get(MerkleTree.index_to_key(this.prefix, 0, i))
|
||||||
if (elementFromTree === element) {
|
if (elementFromTree === element) {
|
||||||
return i
|
return i
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
class JsStorage {
|
class JsStorage {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.db = {}
|
this.db = {}
|
||||||
@ -30,7 +28,7 @@ class JsStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
put_batch(key_values) {
|
put_batch(key_values) {
|
||||||
key_values.forEach(element => {
|
key_values.forEach((element) => {
|
||||||
this.db[element.key] = element.value
|
this.db[element.key] = element.value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ function send(method, params = []) {
|
|||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
method,
|
method,
|
||||||
params
|
params,
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
return err ? reject(err) : resolve(res)
|
return err ? reject(err) : resolve(res)
|
||||||
})
|
})
|
||||||
@ -48,5 +48,5 @@ module.exports = {
|
|||||||
minerStop,
|
minerStop,
|
||||||
minerStart,
|
minerStart,
|
||||||
increaseTime,
|
increaseTime,
|
||||||
traceTransaction
|
traceTransaction,
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
/* global artifacts */
|
|
||||||
const Migrations = artifacts.require('Migrations')
|
|
||||||
|
|
||||||
module.exports = function(deployer) {
|
|
||||||
if(deployer.network === 'mainnet') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
deployer.deploy(Migrations)
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
/* global artifacts */
|
/* global artifacts */
|
||||||
const Hasher = artifacts.require('Hasher')
|
const Hasher = artifacts.require('Hasher')
|
||||||
|
|
||||||
module.exports = async function(deployer) {
|
module.exports = async function (deployer) {
|
||||||
await deployer.deploy(Hasher)
|
await deployer.deploy(Hasher)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* global artifacts */
|
/* global artifacts */
|
||||||
const Verifier = artifacts.require('Verifier')
|
const Verifier = artifacts.require('Verifier')
|
||||||
|
|
||||||
module.exports = function(deployer) {
|
module.exports = function (deployer) {
|
||||||
deployer.deploy(Verifier)
|
deployer.deploy(Verifier)
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,19 @@ const ETHTornado = artifacts.require('ETHTornado')
|
|||||||
const Verifier = artifacts.require('Verifier')
|
const Verifier = artifacts.require('Verifier')
|
||||||
const hasherContract = artifacts.require('Hasher')
|
const hasherContract = artifacts.require('Hasher')
|
||||||
|
|
||||||
|
module.exports = function (deployer, network, accounts) {
|
||||||
module.exports = function(deployer, network, accounts) {
|
|
||||||
return deployer.then(async () => {
|
return deployer.then(async () => {
|
||||||
const { MERKLE_TREE_HEIGHT, ETH_AMOUNT } = process.env
|
const { MERKLE_TREE_HEIGHT, ETH_AMOUNT } = process.env
|
||||||
const verifier = await Verifier.deployed()
|
const verifier = await Verifier.deployed()
|
||||||
const hasherInstance = await hasherContract.deployed()
|
const hasherInstance = await hasherContract.deployed()
|
||||||
await ETHTornado.link(hasherContract, hasherInstance.address)
|
await ETHTornado.link(hasherContract, hasherInstance.address)
|
||||||
const tornado = await deployer.deploy(ETHTornado, verifier.address, ETH_AMOUNT, MERKLE_TREE_HEIGHT, accounts[0])
|
const tornado = await deployer.deploy(
|
||||||
console.log('ETHTornado\'s address ', tornado.address)
|
ETHTornado,
|
||||||
|
verifier.address,
|
||||||
|
ETH_AMOUNT,
|
||||||
|
MERKLE_TREE_HEIGHT,
|
||||||
|
accounts[0],
|
||||||
|
)
|
||||||
|
console.log('ETHTornado address ', tornado.address)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,14 @@ const Verifier = artifacts.require('Verifier')
|
|||||||
const hasherContract = artifacts.require('Hasher')
|
const hasherContract = artifacts.require('Hasher')
|
||||||
const ERC20Mock = artifacts.require('ERC20Mock')
|
const ERC20Mock = artifacts.require('ERC20Mock')
|
||||||
|
|
||||||
|
module.exports = function (deployer, network, accounts) {
|
||||||
module.exports = function(deployer, network, accounts) {
|
|
||||||
return deployer.then(async () => {
|
return deployer.then(async () => {
|
||||||
const { MERKLE_TREE_HEIGHT, ERC20_TOKEN, TOKEN_AMOUNT } = process.env
|
const { MERKLE_TREE_HEIGHT, ERC20_TOKEN, TOKEN_AMOUNT } = process.env
|
||||||
const verifier = await Verifier.deployed()
|
const verifier = await Verifier.deployed()
|
||||||
const hasherInstance = await hasherContract.deployed()
|
const hasherInstance = await hasherContract.deployed()
|
||||||
await ERC20Tornado.link(hasherContract, hasherInstance.address)
|
await ERC20Tornado.link(hasherContract, hasherInstance.address)
|
||||||
let token = ERC20_TOKEN
|
let token = ERC20_TOKEN
|
||||||
if(token === '') {
|
if (token === '') {
|
||||||
const tokenInstance = await deployer.deploy(ERC20Mock)
|
const tokenInstance = await deployer.deploy(ERC20Mock)
|
||||||
token = tokenInstance.address
|
token = tokenInstance.address
|
||||||
}
|
}
|
||||||
@ -25,6 +24,6 @@ module.exports = function(deployer, network, accounts) {
|
|||||||
accounts[0],
|
accounts[0],
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
console.log('ERC20Tornado\'s address ', tornado.address)
|
console.log('ERC20Tornado address ', tornado.address)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,15 @@ const AMOUNT = '1'
|
|||||||
// CURRENCY = 'ETH'
|
// CURRENCY = 'ETH'
|
||||||
|
|
||||||
/** Generate random number of specified byte length */
|
/** Generate random number of specified byte length */
|
||||||
const rbigint = nbytes => bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
const rbigint = (nbytes) => bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
||||||
|
|
||||||
/** Compute pedersen hash */
|
/** Compute pedersen hash */
|
||||||
const pedersenHash = data => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0]
|
const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0]
|
||||||
|
|
||||||
/** BigNumber to hex string of specified length */
|
/** BigNumber to hex string of specified length */
|
||||||
const toHex = (number, length = 32) => '0x' + (number instanceof Buffer ? number.toString('hex') : bigInt(number).toString(16)).padStart(length * 2, '0')
|
const toHex = (number, length = 32) =>
|
||||||
|
'0x' +
|
||||||
|
(number instanceof Buffer ? number.toString('hex') : bigInt(number).toString(16)).padStart(length * 2, '0')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create deposit object from secret and nullifier
|
* Create deposit object from secret and nullifier
|
||||||
@ -43,7 +45,9 @@ function createDeposit(nullifier, secret) {
|
|||||||
async function deposit() {
|
async function deposit() {
|
||||||
const deposit = createDeposit(rbigint(31), rbigint(31))
|
const deposit = createDeposit(rbigint(31), rbigint(31))
|
||||||
console.log('Sending deposit transaction...')
|
console.log('Sending deposit transaction...')
|
||||||
const tx = await contract.methods.deposit(toHex(deposit.commitment)).send({ value: toWei(AMOUNT), from: web3.eth.defaultAccount, gas:2e6 })
|
const tx = await contract.methods
|
||||||
|
.deposit(toHex(deposit.commitment))
|
||||||
|
.send({ value: toWei(AMOUNT), from: web3.eth.defaultAccount, gas: 2e6 })
|
||||||
console.log(`https://kovan.etherscan.io/tx/${tx.transactionHash}`)
|
console.log(`https://kovan.etherscan.io/tx/${tx.transactionHash}`)
|
||||||
return `tornado-eth-${AMOUNT}-${netId}-${toHex(deposit.preimage, 62)}`
|
return `tornado-eth-${AMOUNT}-${netId}-${toHex(deposit.preimage, 62)}`
|
||||||
}
|
}
|
||||||
@ -87,11 +91,11 @@ async function generateMerkleProof(deposit) {
|
|||||||
const events = await contract.getPastEvents('Deposit', { fromBlock: 0, toBlock: 'latest' })
|
const events = await contract.getPastEvents('Deposit', { fromBlock: 0, toBlock: 'latest' })
|
||||||
const leaves = events
|
const leaves = events
|
||||||
.sort((a, b) => a.returnValues.leafIndex - b.returnValues.leafIndex) // Sort events in chronological order
|
.sort((a, b) => a.returnValues.leafIndex - b.returnValues.leafIndex) // Sort events in chronological order
|
||||||
.map(e => e.returnValues.commitment)
|
.map((e) => e.returnValues.commitment)
|
||||||
const tree = new merkleTree(MERKLE_TREE_HEIGHT, leaves)
|
const tree = new merkleTree(MERKLE_TREE_HEIGHT, leaves)
|
||||||
|
|
||||||
// Find current commitment in the tree
|
// Find current commitment in the tree
|
||||||
let depositEvent = events.find(e => e.returnValues.commitment === toHex(deposit.commitment))
|
let depositEvent = events.find((e) => e.returnValues.commitment === toHex(deposit.commitment))
|
||||||
let leafIndex = depositEvent ? depositEvent.returnValues.leafIndex : -1
|
let leafIndex = depositEvent ? depositEvent.returnValues.leafIndex : -1
|
||||||
|
|
||||||
// Validate that our data is correct (optional)
|
// Validate that our data is correct (optional)
|
||||||
@ -141,14 +145,16 @@ async function generateSnarkProof(deposit, recipient) {
|
|||||||
toHex(input.recipient, 20),
|
toHex(input.recipient, 20),
|
||||||
toHex(input.relayer, 20),
|
toHex(input.relayer, 20),
|
||||||
toHex(input.fee),
|
toHex(input.fee),
|
||||||
toHex(input.refund)
|
toHex(input.refund),
|
||||||
]
|
]
|
||||||
|
|
||||||
return { proof, args }
|
return { proof, args }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
web3 = new Web3(new Web3.providers.HttpProvider(RPC_URL, { timeout: 5 * 60 * 1000 }), null, { transactionConfirmationBlocks: 1 })
|
web3 = new Web3(new Web3.providers.HttpProvider(RPC_URL, { timeout: 5 * 60 * 1000 }), null, {
|
||||||
|
transactionConfirmationBlocks: 1,
|
||||||
|
})
|
||||||
circuit = require('./build/circuits/withdraw.json')
|
circuit = require('./build/circuits/withdraw.json')
|
||||||
proving_key = fs.readFileSync('build/circuits/withdraw_proving_key.bin').buffer
|
proving_key = fs.readFileSync('build/circuits/withdraw_proving_key.bin').buffer
|
||||||
groth16 = await buildGroth16()
|
groth16 = await buildGroth16()
|
||||||
|
8408
package-lock.json
generated
8408
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -19,7 +19,10 @@
|
|||||||
"migrate:kovan": "npx truffle migrate --network kovan --reset",
|
"migrate:kovan": "npx truffle migrate --network kovan --reset",
|
||||||
"migrate:rinkeby": "npx truffle migrate --network rinkeby --reset",
|
"migrate:rinkeby": "npx truffle migrate --network rinkeby --reset",
|
||||||
"migrate:mainnet": "npx truffle migrate --network mainnet",
|
"migrate:mainnet": "npx truffle migrate --network mainnet",
|
||||||
"eslint": "npx eslint --ignore-path .gitignore .",
|
"eslint": "eslint --ext .js --ignore-path .gitignore .",
|
||||||
|
"prettier:check": "prettier --check . --config .prettierrc",
|
||||||
|
"prettier:fix": "prettier --write . --config .prettierrc",
|
||||||
|
"lint": "yarn eslint && yarn prettier:check",
|
||||||
"flat": "npx truffle-flattener contracts/ETHTornado.sol > ETHTornado_flat.sol && npx truffle-flattener contracts/ERC20Tornado.sol > ERC20Tornado_flat.sol",
|
"flat": "npx truffle-flattener contracts/ETHTornado.sol > ETHTornado_flat.sol && npx truffle-flattener contracts/ERC20Tornado.sol > ERC20Tornado_flat.sol",
|
||||||
"download": "node downloadKeys.js"
|
"download": "node downloadKeys.js"
|
||||||
},
|
},
|
||||||
@ -31,6 +34,7 @@
|
|||||||
"@truffle/contract": "^4.0.39",
|
"@truffle/contract": "^4.0.39",
|
||||||
"@truffle/hdwallet-provider": "^1.0.24",
|
"@truffle/hdwallet-provider": "^1.0.24",
|
||||||
"axios": "^0.19.0",
|
"axios": "^0.19.0",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
"bn-chai": "^1.0.1",
|
"bn-chai": "^1.0.1",
|
||||||
"browserify": "^16.5.0",
|
"browserify": "^16.5.0",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
@ -39,10 +43,15 @@
|
|||||||
"circomlib": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc",
|
"circomlib": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc",
|
||||||
"commander": "^4.1.1",
|
"commander": "^4.1.1",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"eslint": "^6.6.0",
|
"eslint": "^7.19.0",
|
||||||
|
"eslint-config-prettier": "^7.2.0",
|
||||||
|
"eslint-plugin-prettier": "^3.3.1",
|
||||||
"eth-json-rpc-filters": "^4.1.1",
|
"eth-json-rpc-filters": "^4.1.1",
|
||||||
"ganache-cli": "^6.7.0",
|
"ganache-cli": "^6.7.0",
|
||||||
|
"prettier": "^2.2.1",
|
||||||
|
"prettier-plugin-solidity": "^1.0.0-beta.3",
|
||||||
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
|
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
|
||||||
|
"solhint-plugin-prettier": "^0.0.5",
|
||||||
"truffle": "^5.0.44",
|
"truffle": "^5.0.44",
|
||||||
"truffle-flattener": "^1.4.2",
|
"truffle-flattener": "^1.4.2",
|
||||||
"web3": "^1.2.2",
|
"web3": "^1.2.2",
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
/* global artifacts, web3, contract */
|
/* global artifacts, web3, contract */
|
||||||
require('chai')
|
require('chai').use(require('bn-chai')(web3.utils.BN)).use(require('chai-as-promised')).should()
|
||||||
.use(require('bn-chai')(web3.utils.BN))
|
|
||||||
.use(require('chai-as-promised'))
|
|
||||||
.should()
|
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
|
||||||
const { toBN } = require('web3-utils')
|
const { toBN } = require('web3-utils')
|
||||||
@ -25,7 +22,11 @@ const MerkleTree = require('../lib/MerkleTree')
|
|||||||
|
|
||||||
const rbigint = (nbytes) => snarkjs.bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
const rbigint = (nbytes) => snarkjs.bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
||||||
const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0]
|
const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0]
|
||||||
const toFixedHex = (number, length = 32) => '0x' + bigInt(number).toString(16).padStart(length * 2, '0')
|
const toFixedHex = (number, length = 32) =>
|
||||||
|
'0x' +
|
||||||
|
bigInt(number)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(length * 2, '0')
|
||||||
const getRandomRecipient = () => rbigint(20)
|
const getRandomRecipient = () => rbigint(20)
|
||||||
|
|
||||||
function generateDeposit() {
|
function generateDeposit() {
|
||||||
@ -38,7 +39,7 @@ function generateDeposit() {
|
|||||||
return deposit
|
return deposit
|
||||||
}
|
}
|
||||||
|
|
||||||
contract('ERC20Tornado', accounts => {
|
contract('ERC20Tornado', (accounts) => {
|
||||||
let tornado
|
let tornado
|
||||||
let token
|
let token
|
||||||
let usdtToken
|
let usdtToken
|
||||||
@ -59,11 +60,7 @@ contract('ERC20Tornado', accounts => {
|
|||||||
let proving_key
|
let proving_key
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(levels, null, prefix)
|
||||||
levels,
|
|
||||||
null,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
tornado = await Tornado.deployed()
|
tornado = await Tornado.deployed()
|
||||||
if (ERC20_TOKEN) {
|
if (ERC20_TOKEN) {
|
||||||
token = await Token.at(ERC20_TOKEN)
|
token = await Token.at(ERC20_TOKEN)
|
||||||
@ -142,7 +139,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
pathIndices: path_index,
|
pathIndices: path_index,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
@ -164,7 +160,7 @@ contract('ERC20Tornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
||||||
|
|
||||||
@ -177,7 +173,9 @@ contract('ERC20Tornado', accounts => {
|
|||||||
const feeBN = toBN(fee.toString())
|
const feeBN = toBN(fee.toString())
|
||||||
balanceTornadoAfter.should.be.eq.BN(toBN(balanceTornadoBefore).sub(toBN(tokenDenomination)))
|
balanceTornadoAfter.should.be.eq.BN(toBN(balanceTornadoBefore).sub(toBN(tokenDenomination)))
|
||||||
balanceRelayerAfter.should.be.eq.BN(toBN(balanceRelayerBefore).add(feeBN))
|
balanceRelayerAfter.should.be.eq.BN(toBN(balanceRelayerBefore).add(feeBN))
|
||||||
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(tokenDenomination).sub(feeBN)))
|
balanceRecieverAfter.should.be.eq.BN(
|
||||||
|
toBN(balanceRecieverBefore).add(toBN(tokenDenomination).sub(feeBN)),
|
||||||
|
)
|
||||||
|
|
||||||
ethBalanceOperatorAfter.should.be.eq.BN(toBN(ethBalanceOperatorBefore))
|
ethBalanceOperatorAfter.should.be.eq.BN(toBN(ethBalanceOperatorBefore))
|
||||||
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore).add(toBN(refund)))
|
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore).add(toBN(refund)))
|
||||||
@ -223,7 +221,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
pathIndices: path_index,
|
pathIndices: path_index,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
@ -243,7 +240,7 @@ contract('ERC20Tornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
||||||
|
|
||||||
@ -256,7 +253,9 @@ contract('ERC20Tornado', accounts => {
|
|||||||
const feeBN = toBN(fee.toString())
|
const feeBN = toBN(fee.toString())
|
||||||
balanceTornadoAfter.should.be.eq.BN(toBN(balanceTornadoBefore).sub(toBN(tokenDenomination)))
|
balanceTornadoAfter.should.be.eq.BN(toBN(balanceTornadoBefore).sub(toBN(tokenDenomination)))
|
||||||
balanceRelayerAfter.should.be.eq.BN(toBN(balanceRelayerBefore).add(feeBN))
|
balanceRelayerAfter.should.be.eq.BN(toBN(balanceRelayerBefore).add(feeBN))
|
||||||
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(tokenDenomination).sub(feeBN)))
|
balanceRecieverAfter.should.be.eq.BN(
|
||||||
|
toBN(balanceRecieverBefore).add(toBN(tokenDenomination).sub(feeBN)),
|
||||||
|
)
|
||||||
|
|
||||||
ethBalanceOperatorAfter.should.be.eq.BN(toBN(ethBalanceOperatorBefore))
|
ethBalanceOperatorAfter.should.be.eq.BN(toBN(ethBalanceOperatorBefore))
|
||||||
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore))
|
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore))
|
||||||
@ -278,7 +277,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
await token.approve(tornado.address, tokenDenomination, { from: user })
|
await token.approve(tornado.address, tokenDenomination, { from: user })
|
||||||
await tornado.deposit(toFixedHex(deposit.commitment), { from: user, gasPrice: '0' })
|
await tornado.deposit(toFixedHex(deposit.commitment), { from: user, gasPrice: '0' })
|
||||||
|
|
||||||
|
|
||||||
const { root, path_elements, path_index } = await tree.path(0)
|
const { root, path_elements, path_index } = await tree.path(0)
|
||||||
// Circuit input
|
// Circuit input
|
||||||
const input = stringifyBigInts({
|
const input = stringifyBigInts({
|
||||||
@ -297,7 +295,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
pathIndices: path_index,
|
pathIndices: path_index,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
@ -307,13 +304,16 @@ contract('ERC20Tornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
let { reason } = await tornado.withdraw(proof, ...args, { value: 1, from: relayer, gasPrice: '0' }).should.be.rejected
|
let { reason } = await tornado.withdraw(proof, ...args, { value: 1, from: relayer, gasPrice: '0' })
|
||||||
|
.should.be.rejected
|
||||||
reason.should.be.equal('Incorrect refund amount received by the contract')
|
reason.should.be.equal('Incorrect refund amount received by the contract')
|
||||||
|
;({ reason } = await tornado.withdraw(proof, ...args, {
|
||||||
|
value: toBN(refund).mul(toBN(2)),
|
||||||
;({ reason } = await tornado.withdraw(proof, ...args, { value: toBN(refund).mul(toBN(2)), from: relayer, gasPrice: '0' }).should.be.rejected)
|
from: relayer,
|
||||||
|
gasPrice: '0',
|
||||||
|
}).should.be.rejected)
|
||||||
reason.should.be.equal('Incorrect refund amount received by the contract')
|
reason.should.be.equal('Incorrect refund amount received by the contract')
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -364,7 +364,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
pathIndices: path_index,
|
pathIndices: path_index,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
@ -385,7 +384,7 @@ contract('ERC20Tornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
||||||
|
|
||||||
@ -401,7 +400,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(tokenDenomination)))
|
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(tokenDenomination)))
|
||||||
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore).add(toBN(refund)).sub(feeBN))
|
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore).add(toBN(refund)).sub(feeBN))
|
||||||
|
|
||||||
|
|
||||||
logs[0].event.should.be.equal('Withdrawal')
|
logs[0].event.should.be.equal('Withdrawal')
|
||||||
logs[0].args.nullifierHash.should.be.eq.BN(toBN(input.nullifierHash.toString()))
|
logs[0].args.nullifierHash.should.be.eq.BN(toBN(input.nullifierHash.toString()))
|
||||||
logs[0].args.relayer.should.be.eq.BN(operator)
|
logs[0].args.relayer.should.be.eq.BN(operator)
|
||||||
@ -453,7 +451,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
pathIndices: path_index,
|
pathIndices: path_index,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
@ -474,7 +471,7 @@ contract('ERC20Tornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
const { logs } = await tornado.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' })
|
||||||
console.log('withdraw done')
|
console.log('withdraw done')
|
||||||
@ -491,7 +488,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(tokenDenomination)))
|
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(tokenDenomination)))
|
||||||
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore).add(toBN(refund)).sub(feeBN))
|
ethBalanceRecieverAfter.should.be.eq.BN(toBN(ethBalanceRecieverBefore).add(toBN(refund)).sub(feeBN))
|
||||||
|
|
||||||
|
|
||||||
logs[0].event.should.be.equal('Withdrawal')
|
logs[0].event.should.be.equal('Withdrawal')
|
||||||
logs[0].args.nullifierHash.should.be.eq.BN(toBN(input.nullifierHash.toString()))
|
logs[0].args.nullifierHash.should.be.eq.BN(toBN(input.nullifierHash.toString()))
|
||||||
logs[0].args.relayer.should.be.eq.BN(operator)
|
logs[0].args.relayer.should.be.eq.BN(operator)
|
||||||
@ -505,10 +501,6 @@ contract('ERC20Tornado', accounts => {
|
|||||||
await revertSnapshot(snapshotId.result)
|
await revertSnapshot(snapshotId.result)
|
||||||
// eslint-disable-next-line require-atomic-updates
|
// eslint-disable-next-line require-atomic-updates
|
||||||
snapshotId = await takeSnapshot()
|
snapshotId = await takeSnapshot()
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(levels, null, prefix)
|
||||||
levels,
|
|
||||||
null,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
/* global artifacts, web3, contract */
|
/* global artifacts, web3, contract */
|
||||||
require('chai')
|
require('chai').use(require('bn-chai')(web3.utils.BN)).use(require('chai-as-promised')).should()
|
||||||
.use(require('bn-chai')(web3.utils.BN))
|
|
||||||
.use(require('chai-as-promised'))
|
|
||||||
.should()
|
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
|
||||||
const { toBN, randomHex } = require('web3-utils')
|
const { toBN, randomHex } = require('web3-utils')
|
||||||
@ -23,7 +20,11 @@ const MerkleTree = require('../lib/MerkleTree')
|
|||||||
|
|
||||||
const rbigint = (nbytes) => snarkjs.bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
const rbigint = (nbytes) => snarkjs.bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
||||||
const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0]
|
const pedersenHash = (data) => circomlib.babyJub.unpackPoint(circomlib.pedersenHash.hash(data))[0]
|
||||||
const toFixedHex = (number, length = 32) => '0x' + bigInt(number).toString(16).padStart(length * 2, '0')
|
const toFixedHex = (number, length = 32) =>
|
||||||
|
'0x' +
|
||||||
|
bigInt(number)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(length * 2, '0')
|
||||||
const getRandomRecipient = () => rbigint(20)
|
const getRandomRecipient = () => rbigint(20)
|
||||||
|
|
||||||
function generateDeposit() {
|
function generateDeposit() {
|
||||||
@ -39,7 +40,7 @@ function generateDeposit() {
|
|||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
function BNArrayToStringArray(array) {
|
function BNArrayToStringArray(array) {
|
||||||
const arrayToPrint = []
|
const arrayToPrint = []
|
||||||
array.forEach(item => {
|
array.forEach((item) => {
|
||||||
arrayToPrint.push(item.toString())
|
arrayToPrint.push(item.toString())
|
||||||
})
|
})
|
||||||
return arrayToPrint
|
return arrayToPrint
|
||||||
@ -51,7 +52,7 @@ function snarkVerify(proof) {
|
|||||||
return snarkjs['groth'].isValid(verification_key, proof, proof.publicSignals)
|
return snarkjs['groth'].isValid(verification_key, proof, proof.publicSignals)
|
||||||
}
|
}
|
||||||
|
|
||||||
contract('ETHTornado', accounts => {
|
contract('ETHTornado', (accounts) => {
|
||||||
let tornado
|
let tornado
|
||||||
const sender = accounts[0]
|
const sender = accounts[0]
|
||||||
const operator = accounts[0]
|
const operator = accounts[0]
|
||||||
@ -69,11 +70,7 @@ contract('ETHTornado', accounts => {
|
|||||||
let proving_key
|
let proving_key
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(levels, null, prefix)
|
||||||
levels,
|
|
||||||
null,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
tornado = await Tornado.deployed()
|
tornado = await Tornado.deployed()
|
||||||
snapshotId = await takeSnapshot()
|
snapshotId = await takeSnapshot()
|
||||||
groth16 = await buildGroth16()
|
groth16 = await buildGroth16()
|
||||||
@ -97,8 +94,8 @@ contract('ETHTornado', accounts => {
|
|||||||
logs[0].args.commitment.should.be.equal(commitment)
|
logs[0].args.commitment.should.be.equal(commitment)
|
||||||
logs[0].args.leafIndex.should.be.eq.BN(0)
|
logs[0].args.leafIndex.should.be.eq.BN(0)
|
||||||
|
|
||||||
commitment = toFixedHex(12);
|
commitment = toFixedHex(12)
|
||||||
({ logs } = await tornado.deposit(commitment, { value, from: accounts[2] }))
|
;({ logs } = await tornado.deposit(commitment, { value, from: accounts[2] }))
|
||||||
|
|
||||||
logs[0].event.should.be.equal('Deposit')
|
logs[0].event.should.be.equal('Deposit')
|
||||||
logs[0].args.commitment.should.be.equal(commitment)
|
logs[0].args.commitment.should.be.equal(commitment)
|
||||||
@ -138,7 +135,8 @@ contract('ETHTornado', accounts => {
|
|||||||
result.should.be.equal(true)
|
result.should.be.equal(true)
|
||||||
|
|
||||||
// nullifier
|
// nullifier
|
||||||
proofData.publicSignals[1] = '133792158246920651341275668520530514036799294649489851421007411546007850802'
|
proofData.publicSignals[1] =
|
||||||
|
'133792158246920651341275668520530514036799294649489851421007411546007850802'
|
||||||
result = snarkVerify(proofData)
|
result = snarkVerify(proofData)
|
||||||
result.should.be.equal(false)
|
result.should.be.equal(false)
|
||||||
proofData = originalProof
|
proofData = originalProof
|
||||||
@ -192,7 +190,6 @@ contract('ETHTornado', accounts => {
|
|||||||
pathIndices: path_index,
|
pathIndices: path_index,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
@ -212,7 +209,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const { logs } = await tornado.withdraw(proof, ...args, { from: relayer, gasPrice: '0' })
|
const { logs } = await tornado.withdraw(proof, ...args, { from: relayer, gasPrice: '0' })
|
||||||
|
|
||||||
@ -226,7 +223,6 @@ contract('ETHTornado', accounts => {
|
|||||||
balanceOperatorAfter.should.be.eq.BN(toBN(balanceOperatorBefore).add(feeBN))
|
balanceOperatorAfter.should.be.eq.BN(toBN(balanceOperatorBefore).add(feeBN))
|
||||||
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(value)).sub(feeBN))
|
balanceRecieverAfter.should.be.eq.BN(toBN(balanceRecieverBefore).add(toBN(value)).sub(feeBN))
|
||||||
|
|
||||||
|
|
||||||
logs[0].event.should.be.equal('Withdrawal')
|
logs[0].event.should.be.equal('Withdrawal')
|
||||||
logs[0].args.nullifierHash.should.be.equal(toFixedHex(input.nullifierHash))
|
logs[0].args.nullifierHash.should.be.equal(toFixedHex(input.nullifierHash))
|
||||||
logs[0].args.relayer.should.be.eq.BN(operator)
|
logs[0].args.relayer.should.be.eq.BN(operator)
|
||||||
@ -262,7 +258,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
await tornado.withdraw(proof, ...args, { from: relayer }).should.be.fulfilled
|
await tornado.withdraw(proof, ...args, { from: relayer }).should.be.fulfilled
|
||||||
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
||||||
@ -292,11 +288,15 @@ contract('ETHTornado', accounts => {
|
|||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
const args = [
|
const args = [
|
||||||
toFixedHex(input.root),
|
toFixedHex(input.root),
|
||||||
toFixedHex(toBN(input.nullifierHash).add(toBN('21888242871839275222246405745257275088548364400416034343698204186575808495617'))),
|
toFixedHex(
|
||||||
|
toBN(input.nullifierHash).add(
|
||||||
|
toBN('21888242871839275222246405745257275088548364400416034343698204186575808495617'),
|
||||||
|
),
|
||||||
|
),
|
||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
||||||
error.reason.should.be.equal('verifier-gte-snark-scalar-field')
|
error.reason.should.be.equal('verifier-gte-snark-scalar-field')
|
||||||
@ -330,7 +330,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
||||||
error.reason.should.be.equal('Fee exceeds transfer value')
|
error.reason.should.be.equal('Fee exceeds transfer value')
|
||||||
@ -365,7 +365,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
||||||
error.reason.should.be.equal('Cannot find your merkle root')
|
error.reason.should.be.equal('Cannot find your merkle root')
|
||||||
@ -398,7 +398,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
let incorrectArgs
|
let incorrectArgs
|
||||||
const originalProof = proof.slice()
|
const originalProof = proof.slice()
|
||||||
@ -410,7 +410,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex('0x0000000000000000000000007a1f9131357404ef86d7c38dbffed2da70321337', 20),
|
toFixedHex('0x0000000000000000000000007a1f9131357404ef86d7c38dbffed2da70321337', 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
let error = await tornado.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected
|
let error = await tornado.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected
|
||||||
error.reason.should.be.equal('Invalid withdraw proof')
|
error.reason.should.be.equal('Invalid withdraw proof')
|
||||||
@ -422,7 +422,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex('0x000000000000000000000000000000000000000000000000015345785d8a0000'),
|
toFixedHex('0x000000000000000000000000000000000000000000000000015345785d8a0000'),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
error = await tornado.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected
|
error = await tornado.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected
|
||||||
error.reason.should.be.equal('Invalid withdraw proof')
|
error.reason.should.be.equal('Invalid withdraw proof')
|
||||||
@ -434,7 +434,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
error = await tornado.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected
|
error = await tornado.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected
|
||||||
error.reason.should.be.equal('Invalid withdraw proof')
|
error.reason.should.be.equal('Invalid withdraw proof')
|
||||||
@ -476,7 +476,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
const error = await tornado.withdraw(proof, ...args, { from: relayer }).should.be.rejected
|
||||||
error.reason.should.be.equal('Refund value is supposed to be zero for ETH instance')
|
error.reason.should.be.equal('Refund value is supposed to be zero for ETH instance')
|
||||||
@ -500,9 +500,8 @@ contract('ETHTornado', accounts => {
|
|||||||
operator.should.be.equal(sender)
|
operator.should.be.equal(sender)
|
||||||
|
|
||||||
const newOperator = accounts[7]
|
const newOperator = accounts[7]
|
||||||
const error = await tornado.changeOperator(newOperator, { from: accounts[7] }).should.be.rejected
|
const error = await tornado.changeOperator(newOperator, { from: accounts[7] }).should.be.rejected
|
||||||
error.reason.should.be.equal('Only operator can call this function.')
|
error.reason.should.be.equal('Only operator can call this function.')
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -523,9 +522,8 @@ contract('ETHTornado', accounts => {
|
|||||||
operator.should.be.equal(sender)
|
operator.should.be.equal(sender)
|
||||||
|
|
||||||
const newVerifier = accounts[7]
|
const newVerifier = accounts[7]
|
||||||
const error = await tornado.updateVerifier(newVerifier, { from: accounts[7] }).should.be.rejected
|
const error = await tornado.updateVerifier(newVerifier, { from: accounts[7] }).should.be.rejected
|
||||||
error.reason.should.be.equal('Only operator can call this function.')
|
error.reason.should.be.equal('Only operator can call this function.')
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -557,7 +555,6 @@ contract('ETHTornado', accounts => {
|
|||||||
pathIndices: path_index,
|
pathIndices: path_index,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
@ -567,7 +564,7 @@ contract('ETHTornado', accounts => {
|
|||||||
toFixedHex(input.recipient, 20),
|
toFixedHex(input.recipient, 20),
|
||||||
toFixedHex(input.relayer, 20),
|
toFixedHex(input.relayer, 20),
|
||||||
toFixedHex(input.fee),
|
toFixedHex(input.fee),
|
||||||
toFixedHex(input.refund)
|
toFixedHex(input.refund),
|
||||||
]
|
]
|
||||||
|
|
||||||
await tornado.withdraw(proof, ...args, { from: relayer, gasPrice: '0' })
|
await tornado.withdraw(proof, ...args, { from: relayer, gasPrice: '0' })
|
||||||
@ -583,10 +580,6 @@ contract('ETHTornado', accounts => {
|
|||||||
await revertSnapshot(snapshotId.result)
|
await revertSnapshot(snapshotId.result)
|
||||||
// eslint-disable-next-line require-atomic-updates
|
// eslint-disable-next-line require-atomic-updates
|
||||||
snapshotId = await takeSnapshot()
|
snapshotId = await takeSnapshot()
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(levels, null, prefix)
|
||||||
levels,
|
|
||||||
null,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
/* global artifacts, web3, contract, assert */
|
/* global artifacts, web3, contract, assert */
|
||||||
require('chai')
|
require('chai').use(require('bn-chai')(web3.utils.BN)).use(require('chai-as-promised')).should()
|
||||||
.use(require('bn-chai')(web3.utils.BN))
|
|
||||||
.use(require('chai-as-promised'))
|
|
||||||
.should()
|
|
||||||
|
|
||||||
const { takeSnapshot, revertSnapshot } = require('../lib/ganacheHelper')
|
const { takeSnapshot, revertSnapshot } = require('../lib/ganacheHelper')
|
||||||
|
|
||||||
@ -20,7 +17,7 @@ const { ETH_AMOUNT, MERKLE_TREE_HEIGHT } = process.env
|
|||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
function BNArrayToStringArray(array) {
|
function BNArrayToStringArray(array) {
|
||||||
const arrayToPrint = []
|
const arrayToPrint = []
|
||||||
array.forEach(item => {
|
array.forEach((item) => {
|
||||||
arrayToPrint.push(item.toString())
|
arrayToPrint.push(item.toString())
|
||||||
})
|
})
|
||||||
return arrayToPrint
|
return arrayToPrint
|
||||||
@ -33,7 +30,7 @@ function toFixedHex(number, length = 32) {
|
|||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
contract('MerkleTreeWithHistory', accounts => {
|
contract('MerkleTreeWithHistory', (accounts) => {
|
||||||
let merkleTreeWithHistory
|
let merkleTreeWithHistory
|
||||||
let hasherInstance
|
let hasherInstance
|
||||||
let levels = MERKLE_TREE_HEIGHT || 16
|
let levels = MERKLE_TREE_HEIGHT || 16
|
||||||
@ -46,11 +43,7 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
let hasher
|
let hasher
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(levels, null, prefix)
|
||||||
levels,
|
|
||||||
null,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
hasherInstance = await hasherContract.deployed()
|
hasherInstance = await hasherContract.deployed()
|
||||||
await MerkleTreeWithHistory.link(hasherContract, hasherInstance.address)
|
await MerkleTreeWithHistory.link(hasherContract, hasherInstance.address)
|
||||||
merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels)
|
merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels)
|
||||||
@ -69,40 +62,26 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
|
|
||||||
describe('merkleTreeLib', () => {
|
describe('merkleTreeLib', () => {
|
||||||
it('index_to_key', () => {
|
it('index_to_key', () => {
|
||||||
assert.equal(
|
assert.equal(MerkleTree.index_to_key('test', 5, 20), 'test_tree_5_20')
|
||||||
MerkleTree.index_to_key('test', 5, 20),
|
|
||||||
'test_tree_5_20',
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('tests insert', async () => {
|
it('tests insert', async () => {
|
||||||
hasher = new hasherImpl()
|
hasher = new hasherImpl()
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(2, null, prefix)
|
||||||
2,
|
|
||||||
null,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
await tree.insert(toFixedHex('5'))
|
await tree.insert(toFixedHex('5'))
|
||||||
let { root, path_elements } = await tree.path(0)
|
let { root, path_elements } = await tree.path(0)
|
||||||
const calculated_root = hasher.hash(null,
|
const calculated_root = hasher.hash(null, hasher.hash(null, '5', path_elements[0]), path_elements[1])
|
||||||
hasher.hash(null, '5', path_elements[0]),
|
|
||||||
path_elements[1]
|
|
||||||
)
|
|
||||||
// console.log(root)
|
// console.log(root)
|
||||||
assert.equal(root, calculated_root)
|
assert.equal(root, calculated_root)
|
||||||
})
|
})
|
||||||
it('creation odd elements count', async () => {
|
it('creation odd elements count', async () => {
|
||||||
const elements = [12, 13, 14, 15, 16, 17, 18, 19, 20]
|
const elements = [12, 13, 14, 15, 16, 17, 18, 19, 20]
|
||||||
for(const [, el] of Object.entries(elements)) {
|
for (const [, el] of Object.entries(elements)) {
|
||||||
await tree.insert(el)
|
await tree.insert(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
const batchTree = new MerkleTree(
|
const batchTree = new MerkleTree(levels, elements, prefix)
|
||||||
levels,
|
for (const [i] of Object.entries(elements)) {
|
||||||
elements,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
for(const [i] of Object.entries(elements)) {
|
|
||||||
const pathViaConstructor = await batchTree.path(i)
|
const pathViaConstructor = await batchTree.path(i)
|
||||||
const pathViaUpdate = await tree.path(i)
|
const pathViaUpdate = await tree.path(i)
|
||||||
pathViaConstructor.should.be.deep.equal(pathViaUpdate)
|
pathViaConstructor.should.be.deep.equal(pathViaUpdate)
|
||||||
@ -111,7 +90,7 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
|
|
||||||
it('should find an element', async () => {
|
it('should find an element', async () => {
|
||||||
const elements = [12, 13, 14, 15, 16, 17, 18, 19, 20]
|
const elements = [12, 13, 14, 15, 16, 17, 18, 19, 20]
|
||||||
for(const [, el] of Object.entries(elements)) {
|
for (const [, el] of Object.entries(elements)) {
|
||||||
await tree.insert(el)
|
await tree.insert(el)
|
||||||
}
|
}
|
||||||
let index = tree.getIndexByElement(13)
|
let index = tree.getIndexByElement(13)
|
||||||
@ -132,16 +111,12 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
|
|
||||||
it('creation even elements count', async () => {
|
it('creation even elements count', async () => {
|
||||||
const elements = [12, 13, 14, 15, 16, 17]
|
const elements = [12, 13, 14, 15, 16, 17]
|
||||||
for(const [, el] of Object.entries(elements)) {
|
for (const [, el] of Object.entries(elements)) {
|
||||||
await tree.insert(el)
|
await tree.insert(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
const batchTree = new MerkleTree(
|
const batchTree = new MerkleTree(levels, elements, prefix)
|
||||||
levels,
|
for (const [i] of Object.entries(elements)) {
|
||||||
elements,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
for(const [i] of Object.entries(elements)) {
|
|
||||||
const pathViaConstructor = await batchTree.path(i)
|
const pathViaConstructor = await batchTree.path(i)
|
||||||
const pathViaUpdate = await tree.path(i)
|
const pathViaUpdate = await tree.path(i)
|
||||||
pathViaConstructor.should.be.deep.equal(pathViaUpdate)
|
pathViaConstructor.should.be.deep.equal(pathViaUpdate)
|
||||||
@ -150,15 +125,11 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
|
|
||||||
it.skip('creation using 30000 elements', () => {
|
it.skip('creation using 30000 elements', () => {
|
||||||
const elements = []
|
const elements = []
|
||||||
for(let i = 1000; i < 31001; i++) {
|
for (let i = 1000; i < 31001; i++) {
|
||||||
elements.push(i)
|
elements.push(i)
|
||||||
}
|
}
|
||||||
console.time('MerkleTree')
|
console.time('MerkleTree')
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(levels, elements, prefix)
|
||||||
levels,
|
|
||||||
elements,
|
|
||||||
prefix,
|
|
||||||
)
|
|
||||||
console.timeEnd('MerkleTree')
|
console.timeEnd('MerkleTree')
|
||||||
// 2,7 GHz Intel Core i7
|
// 2,7 GHz Intel Core i7
|
||||||
// 1000 : 1949.084ms
|
// 1000 : 1949.084ms
|
||||||
@ -184,8 +155,8 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
const levels = 6
|
const levels = 6
|
||||||
const merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels)
|
const merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels)
|
||||||
|
|
||||||
for (let i = 0; i < 2**levels; i++) {
|
for (let i = 0; i < 2 ** levels; i++) {
|
||||||
await merkleTreeWithHistory.insert(toFixedHex(i+42)).should.be.fulfilled
|
await merkleTreeWithHistory.insert(toFixedHex(i + 42)).should.be.fulfilled
|
||||||
}
|
}
|
||||||
|
|
||||||
let error = await merkleTreeWithHistory.insert(toFixedHex(1337)).should.be.rejected
|
let error = await merkleTreeWithHistory.insert(toFixedHex(1337)).should.be.rejected
|
||||||
@ -230,18 +201,11 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await revertSnapshot(snapshotId.result)
|
await revertSnapshot(snapshotId.result)
|
||||||
// eslint-disable-next-line require-atomic-updates
|
// eslint-disable-next-line require-atomic-updates
|
||||||
snapshotId = await takeSnapshot()
|
snapshotId = await takeSnapshot()
|
||||||
hasher = new hasherImpl()
|
hasher = new hasherImpl()
|
||||||
tree = new MerkleTree(
|
tree = new MerkleTree(levels, null, prefix, null, hasher)
|
||||||
levels,
|
|
||||||
null,
|
|
||||||
prefix,
|
|
||||||
null,
|
|
||||||
hasher,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
require("dotenv").config();
|
require('dotenv').config()
|
||||||
const HDWalletProvider = require("@truffle/hdwallet-provider");
|
const HDWalletProvider = require('@truffle/hdwallet-provider')
|
||||||
const utils = require("web3-utils");
|
const utils = require('web3-utils')
|
||||||
// const infuraKey = "fj4jll3k.....";
|
// const infuraKey = "fj4jll3k.....";
|
||||||
//
|
//
|
||||||
// const fs = require('fs');
|
// const fs = require('fs');
|
||||||
@ -25,9 +25,9 @@ module.exports = {
|
|||||||
// options below to some value.
|
// options below to some value.
|
||||||
|
|
||||||
development: {
|
development: {
|
||||||
host: "127.0.0.1", // Localhost (default: none)
|
host: '127.0.0.1', // Localhost (default: none)
|
||||||
port: 8545, // Standard Ethereum port (default: none)
|
port: 8545, // Standard Ethereum port (default: none)
|
||||||
network_id: "*", // Any network (default: none)
|
network_id: '*', // Any network (default: none)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Another network with more advanced options...
|
// Another network with more advanced options...
|
||||||
@ -46,11 +46,11 @@ module.exports = {
|
|||||||
provider: () =>
|
provider: () =>
|
||||||
new HDWalletProvider(
|
new HDWalletProvider(
|
||||||
process.env.PRIVATE_KEY,
|
process.env.PRIVATE_KEY,
|
||||||
"https://kovan.infura.io/v3/97c8bf358b9942a9853fab1ba93dc5b3"
|
'https://kovan.infura.io/v3/97c8bf358b9942a9853fab1ba93dc5b3',
|
||||||
),
|
),
|
||||||
network_id: 42,
|
network_id: 42,
|
||||||
gas: 6000000,
|
gas: 6000000,
|
||||||
gasPrice: utils.toWei("1", "gwei"),
|
gasPrice: utils.toWei('1', 'gwei'),
|
||||||
// confirmations: 0,
|
// confirmations: 0,
|
||||||
// timeoutBlocks: 200,
|
// timeoutBlocks: 200,
|
||||||
skipDryRun: true,
|
skipDryRun: true,
|
||||||
@ -59,11 +59,11 @@ module.exports = {
|
|||||||
provider: () =>
|
provider: () =>
|
||||||
new HDWalletProvider(
|
new HDWalletProvider(
|
||||||
process.env.PRIVATE_KEY,
|
process.env.PRIVATE_KEY,
|
||||||
"https://goerli.infura.io/v3/d34c08f2cb7c4111b645d06ac7e35ba8"
|
'https://goerli.infura.io/v3/d34c08f2cb7c4111b645d06ac7e35ba8',
|
||||||
),
|
),
|
||||||
network_id: 5,
|
network_id: 5,
|
||||||
gas: 6000000,
|
gas: 6000000,
|
||||||
gasPrice: utils.toWei("1", "gwei"),
|
gasPrice: utils.toWei('1', 'gwei'),
|
||||||
// confirmations: 0,
|
// confirmations: 0,
|
||||||
// timeoutBlocks: 200,
|
// timeoutBlocks: 200,
|
||||||
skipDryRun: true,
|
skipDryRun: true,
|
||||||
@ -72,24 +72,20 @@ module.exports = {
|
|||||||
provider: () =>
|
provider: () =>
|
||||||
new HDWalletProvider(
|
new HDWalletProvider(
|
||||||
process.env.PRIVATE_KEY,
|
process.env.PRIVATE_KEY,
|
||||||
"https://rinkeby.infura.io/v3/97c8bf358b9942a9853fab1ba93dc5b3"
|
'https://rinkeby.infura.io/v3/97c8bf358b9942a9853fab1ba93dc5b3',
|
||||||
),
|
),
|
||||||
network_id: 4,
|
network_id: 4,
|
||||||
gas: 6000000,
|
gas: 6000000,
|
||||||
gasPrice: utils.toWei("1", "gwei"),
|
gasPrice: utils.toWei('1', 'gwei'),
|
||||||
// confirmations: 0,
|
// confirmations: 0,
|
||||||
// timeoutBlocks: 200,
|
// timeoutBlocks: 200,
|
||||||
skipDryRun: true,
|
skipDryRun: true,
|
||||||
},
|
},
|
||||||
mainnet: {
|
mainnet: {
|
||||||
provider: () =>
|
provider: () => new HDWalletProvider(process.env.PRIVATE_KEY, 'http://ethereum-rpc.trustwalletapp.com'),
|
||||||
new HDWalletProvider(
|
|
||||||
process.env.PRIVATE_KEY,
|
|
||||||
"http://ethereum-rpc.trustwalletapp.com"
|
|
||||||
),
|
|
||||||
network_id: 1,
|
network_id: 1,
|
||||||
gas: 6000000,
|
gas: 6000000,
|
||||||
gasPrice: utils.toWei("2", "gwei"),
|
gasPrice: utils.toWei('2', 'gwei'),
|
||||||
// confirmations: 0,
|
// confirmations: 0,
|
||||||
// timeoutBlocks: 200,
|
// timeoutBlocks: 200,
|
||||||
skipDryRun: true,
|
skipDryRun: true,
|
||||||
@ -111,7 +107,7 @@ module.exports = {
|
|||||||
// Configure your compilers
|
// Configure your compilers
|
||||||
compilers: {
|
compilers: {
|
||||||
solc: {
|
solc: {
|
||||||
version: "0.6.12", // Fetch exact version from solc-bin (default: truffle's version)
|
version: '0.6.12', // Fetch exact version from solc-bin (default: truffle's version)
|
||||||
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
||||||
settings: {
|
settings: {
|
||||||
// See the solidity docs for advice about optimization and evmVersion
|
// See the solidity docs for advice about optimization and evmVersion
|
||||||
@ -123,12 +119,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
external: {
|
external: {
|
||||||
command: "node ./compileHasher.js",
|
command: 'node ./compileHasher.js',
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
path: "./build/Hasher.json",
|
path: './build/Hasher.json',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user