diff --git a/.env.example b/.env.example index 3bd63c5..709df76 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,9 @@ REGULAR_TORNADO_WITHDRAW_FEE=2.5 MINING_SERVICE_FEE=2.5 APP_PORT=8000 +TORN_ETH_PRICE=7000000000000000 +REWARD_ACCOUNT= + # Resubmitter params: # how often the watcher will check the first pending tx (in seconds) NONCE_WATCHER_INTERVAL=30 diff --git a/config.js b/src/config.js similarity index 95% rename from config.js rename to src/config.js index 3cdbc4b..26f2b41 100644 --- a/config.js +++ b/src/config.js @@ -1,13 +1,8 @@ require('dotenv').config() -const jobType = require('./src/jobTypes') +const jobType = require('./jobTypes') -function updateConfig(options) { - config = Object.assign(config, options) -} - -let config = { - updateConfig, +module.exports = { netId: Number(process.env.NET_ID) || 42, redisUrl: process.env.REDIS_URL || 'redis://127.0.0.1:6379', rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/', @@ -156,13 +151,11 @@ let config = { port: process.env.APP_PORT || 8000, tornadoServiceFee: Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE), miningServiceFee: Number(process.env.MINING_SERVICE_FEE), - rewardAccount: '0x03Ebd0748Aa4D1457cF479cce56309641e0a98F5', - tornEthPrice: '7000000000000000', + tornEthPrice: process.env.TORN_ETH_PRICE || '7000000000000000', + rewardAccount: process.env.REWARD_ACCOUNT, gasLimits: { [jobType.TORNADO_WITHDRAW]: 350000, [jobType.MINING_REWARD]: 800000, [jobType.MINING_WITHDRAW]: 800000, }, } - -module.exports = config diff --git a/src/priceWatcher.js b/src/priceWatcher.js index e52ac9e..d229155 100644 --- a/src/priceWatcher.js +++ b/src/priceWatcher.js @@ -1,5 +1,5 @@ const Redis = require('ioredis') -const { redisUrl, oracleAddress, oracleRpcUrl } = require('../config') +const { redisUrl, oracleAddress, oracleRpcUrl, tornEthPrice } = require('./config') const { getArgsForOracle, setSafeInterval } = require('./utils') const redis = new Redis(redisUrl) const Web3 = require('web3') @@ -15,6 +15,7 @@ async function main() { acc[currencyLookup[tokenAddresses[i]]] = price return acc }, {}) + ethPrices.torn = tornEthPrice await redis.hmset('prices', ethPrices) console.log('Wrote following prices to redis', ethPrices) } diff --git a/src/queue.js b/src/queue.js index 9180833..433eeed 100644 --- a/src/queue.js +++ b/src/queue.js @@ -1,7 +1,7 @@ const { v4: uuid } = require('uuid') const Queue = require('bull') const Redis = require('ioredis') -const { redisUrl } = require('../config') +const { redisUrl } = require('./config') const redis = new Redis(redisUrl) const queue = new Queue('proofs', redisUrl) diff --git a/src/server.js b/src/server.js index 2e99007..587f906 100644 --- a/src/server.js +++ b/src/server.js @@ -1,8 +1,9 @@ const express = require('express') const status = require('./status') const controller = require('./controller') -const { port } = require('../config') +const { port, rewardAccount } = require('./config') const { version } = require('../package.json') +const { isAddress } = require('web3-utils') const app = express() app.use(express.json()) @@ -32,5 +33,9 @@ app.post('/relay', controller.tornadoWithdraw) app.post('/v1/miningReward', controller.miningReward) app.post('/v1/miningWithdraw', controller.miningWithdraw) +if (!isAddress(rewardAccount)) { + throw new Error('No REWARD_ACCOUNT specified') +} + app.listen(port) console.log(`Relayer ${version} started on port ${port}`) diff --git a/src/status.js b/src/status.js index aed34c6..d049533 100644 --- a/src/status.js +++ b/src/status.js @@ -1,28 +1,19 @@ const queue = require('./queue') -const { GasPriceOracle } = require('gas-price-oracle') -const gasPriceOracle = new GasPriceOracle() -const { netId, tornadoServiceFee, miningServiceFee, instances } = require('../config') +const { netId, tornadoServiceFee, miningServiceFee, instances, redisUrl, rewardAccount } = require('./config') const { version } = require('../package.json') +const Redis = require('ioredis') +const redis = new Redis(redisUrl) async function status(req, res) { - const ethPrices = { - dai: '6700000000000000', // 0.0067 - cdai: '157380000000000', - cusdc: '164630000000000', - usdc: '7878580000000000', - usdt: '7864940000000000', - } + const ethPrices = await redis.hgetall('prices') res.json({ - relayerAddress: require('../config').rewardAccount, - instances: instances.netId42, - gasPrices: await gasPriceOracle.gasPrices(), + rewardAccount, + instances: instances[`netId${netId}`], netId, ethPrices, tornadoServiceFee, miningServiceFee, - nonce: 123, version, - latestBlock: 12312312, }) } diff --git a/src/treeWatcher.js b/src/treeWatcher.js index 64a3877..7d02295 100644 --- a/src/treeWatcher.js +++ b/src/treeWatcher.js @@ -1,5 +1,5 @@ const MerkleTree = require('fixed-merkle-tree') -const { redisUrl, rpcUrl, minerMerkleTreeHeight, minerAddress } = require('../config') +const { redisUrl, rpcUrl, minerMerkleTreeHeight, minerAddress } = require('./config') const { poseidonHash2 } = require('./utils') const { toBN } = require('web3-utils') const Redis = require('ioredis') diff --git a/src/utils.js b/src/utils.js index becbee8..32297ec 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,4 +1,4 @@ -const { instances, netId } = require('../config') +const { instances, netId } = require('./config') const { poseidon } = require('circomlib') const { toBN, toChecksumAddress, BN } = require('web3-utils') diff --git a/src/validator.js b/src/validator.js index 7d5353d..17297b1 100644 --- a/src/validator.js +++ b/src/validator.js @@ -1,5 +1,6 @@ const { isAddress, toChecksumAddress } = require('web3-utils') const { getInstance } = require('./utils') +const { rewardAccount } = require('./config') const Ajv = require('ajv') const ajv = new Ajv({ format: 'fast' }) @@ -29,7 +30,7 @@ ajv.addKeyword('isKnownContract', { ajv.addKeyword('isFeeRecipient', { validate: (schema, data) => { try { - return require('../config').rewardAccount === toChecksumAddress(data) + return toChecksumAddress(rewardAccount) === toChecksumAddress(data) } catch (e) { return false } diff --git a/src/worker.js b/src/worker.js index 34280c5..6539b15 100644 --- a/src/worker.js +++ b/src/worker.js @@ -24,7 +24,7 @@ const { tornadoServiceFee, miningServiceFee, tornEthPrice, -} = require('../config') +} = require('./config') const { TxManager } = require('tx-manager') const { Controller } = require('tornado-cash-anonymity-mining') @@ -102,7 +102,7 @@ async function checkTornadoFee({ args, contract }) { const { fast } = await gasPriceOracle.gasPrices() const ethPrice = await redis.hget('prices', currency) - const expense = toBN(toWei(fast.toString(), 'gwei')).mul(toBN(gasLimits.TORNADO_WITHDRAW)) + const expense = toBN(toWei(fast.toString(), 'gwei')).mul(toBN(gasLimits[jobType.TORNADO_WITHDRAW])) const feePercent = toBN(fromDecimals(amount, decimals)) .mul(toBN(tornadoServiceFee * 1e10)) .div(toBN(1e10 * 100)) @@ -134,18 +134,20 @@ async function checkTornadoFee({ args, contract }) { async function checkMiningFee({ args }) { const swap = new web3.eth.Contract(swapABI, swapAddress) - const TornAmount = await swap.methods.getExpectedReturn(args.fee).call() - console.log('TornAmount', TornAmount) + const tornAmount = await swap.methods.getExpectedReturn(args.fee).call() const { fast } = await gasPriceOracle.gasPrices() + const ethPrice = await redis.hget('prices', 'torn') const expense = toBN(toWei(fast.toString(), 'gwei')).mul(toBN(gasLimits[args.type])) + /* eslint-disable */ const feePercent = args.type === jobType.MINING_REWARD ? 0 - : toBN(args.amount) - .mul(toBN(miningServiceFee * 1e10)) - .div(toBN(1e10 * 100)) - let desiredFee = expense.mul(toBN(1e18)).div(toBN(tornEthPrice)).add(feePercent) + : toBN(tornAmount) + .mul(toBN(miningServiceFee * 1e10)) + .div(toBN(1e10 * 100)) + /* eslint-enable */ + let desiredFee = expense.mul(toBN(1e18)).div(toBN(ethPrice)).add(feePercent) console.log( 'sent fee, desired fee, feePercent', @@ -153,7 +155,7 @@ async function checkMiningFee({ args }) { fromWei(desiredFee.toString()), fromWei(feePercent.toString()), ) - if (args.fee.lt(desiredFee)) { + if (toBN(tornAmount).lt(desiredFee)) { throw new Error('Provided fee is not enough. Probably it is a Gas Price spike, try to resubmit.') } }