From d063bc266bb34556e33040f395efc7182c65884d Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 18 Dec 2019 22:25:09 +0300 Subject: [PATCH 01/12] decimals support --- config.js | 20 ++++++++++++++++ src/utils.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/config.js b/config.js index 32f010a..695ab59 100644 --- a/config.js +++ b/config.js @@ -17,6 +17,16 @@ module.exports = { tokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f', decimals: 18 }, + usdc: { + mixerAddress: { + '100': undefined, + '500': undefined, + '1000': undefined, + '5000': undefined + }, + tokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + decimals: 6 + }, eth: { mixerAddress: { '0.1': '0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc', @@ -38,6 +48,16 @@ module.exports = { tokenAddress: '0x8c158c7e57161dd4d3cb02bf1a3a97fcc78b75fd', decimals: 18 }, + usdc: { + mixerAddress: { + '100': '0x42d096a9194a18DAA2d2D95a70D8dA80DeFFB645', + '500': undefined, + '1000': undefined, + '5000': undefined + }, + tokenAddress: '0x7f5939049c0D7D7dFC484f64600c9306F79a0D3F', + decimals: 6 + }, eth: { mixerAddress: { '0.1': '0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f', diff --git a/src/utils.js b/src/utils.js index 7b21fde..fe6265d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,4 +1,4 @@ -const { isHexStrict, toBN, toWei } = require('web3-utils') +const { isHexStrict, toBN, toWei, BN } = require('web3-utils') const { netId, mixers, relayerServiceFee } = require('../config') function isValidProof(proof) { @@ -59,9 +59,62 @@ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)) } +function fromDecimals(value, decimals) { + value = value.toString() + let ether = value.toString() + const base = new BN('10').pow(new BN(decimals)) + const baseLength = base.toString(10).length - 1 || 1 + + const negative = ether.substring(0, 1) === '-' + if (negative) { + ether = ether.substring(1) + } + + if (ether === '.') { + throw new Error('[ethjs-unit] while converting number ' + value + ' to wei, invalid value') + } + + // Split it into a whole and fractional part + const comps = ether.split('.') + if (comps.length > 2) { + throw new Error( + '[ethjs-unit] while converting number ' + value + ' to wei, too many decimal points' + ) + } + + let whole = comps[0] + let fraction = comps[1] + + if (!whole) { + whole = '0' + } + if (!fraction) { + fraction = '0' + } + if (fraction.length > baseLength) { + throw new Error( + '[ethjs-unit] while converting number ' + value + ' to wei, too many decimal places' + ) + } + + while (fraction.length < baseLength) { + fraction += '0' + } + + whole = new BN(whole) + fraction = new BN(fraction) + let wei = whole.mul(base).add(fraction) + + if (negative) { + wei = wei.mul(negative) + } + + return new BN(wei.toString(10), 10) +} + function isEnoughFee({ gas, gasPrices, currency, amount, refund, ethPrices, fee }) { - // TODO tokens can have less then 18 decimals - const feePercent = toBN(toWei(amount)).mul(toBN(relayerServiceFee * 10)).div(toBN('1000')) + const { decimals } = mixers[`netId${netId}`][currency] + const feePercent = toBN(fromDecimals(amount, decimals)).mul(toBN(relayerServiceFee * 10)).div(toBN('1000')) const expense = toBN(toWei(gasPrices.fast.toString(), 'gwei')).mul(toBN(gas)) let desiredFee switch (currency) { @@ -69,16 +122,16 @@ function isEnoughFee({ gas, gasPrices, currency, amount, refund, ethPrices, fee desiredFee = expense.add(feePercent) break } - case 'dai': { + default: { desiredFee = expense.add(refund) - .mul(toBN(10 ** 18)) - .div(toBN(ethPrices.dai)) + .mul(toBN(10 ** decimals)) + .div(toBN(ethPrices[currency])) desiredFee = desiredFee.add(feePercent) break } } - console.log('desired fee, feePercent', desiredFee.toString(), feePercent.toString()) + console.log('sent fee, desired fee, feePercent', fee.toString(), desiredFee.toString(), feePercent.toString()) if (fee.lt(desiredFee)) { return { isEnough: false, reason: 'Not enough fee' } } From 4bdd6b25c0e662cb7df241a7eed43957254331be Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 18 Dec 2019 22:35:25 +0300 Subject: [PATCH 02/12] add version --- config.js | 1 + src/index.js | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/config.js b/config.js index 695ab59..0ac3336 100644 --- a/config.js +++ b/config.js @@ -1,6 +1,7 @@ require('dotenv').config() module.exports = { + version: '1.0', netId: Number(process.env.NET_ID) || 42, redisUrl: process.env.REDIS_URL, rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/v3/a3f4d001c1fc4a359ea70dd27fd9cb51', diff --git a/src/index.js b/src/index.js index 22f47cb..2e67b15 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ const express = require('express') -const { netId, port, relayerServiceFee } = require('../config') +const { netId, port, relayerServiceFee, version } = require('../config') const relayController = require('./relayController') const { fetcher, web3 } = require('./instances') const { getMixers } = require('./utils') @@ -31,7 +31,16 @@ app.get('/', function (req, res) { app.get('/status', async function (req, res) { let nonce = await redisClient.get('nonce') const { ethPrices, gasPrices } = fetcher - res.json({ relayerAddress: web3.eth.defaultAccount, mixers, gasPrices, netId, ethPrices, relayerServiceFee, nonce }) + res.json({ + relayerAddress: web3.eth.defaultAccount, + mixers, + gasPrices, + netId, + ethPrices, + relayerServiceFee, + nonce, + version + }) }) app.post('/relay', relayController) From c480707f635418d8c6834e8829c8c2b69741eb8a Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Wed, 18 Dec 2019 19:36:41 -0800 Subject: [PATCH 03/12] add missing returns --- src/relayController.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/relayController.js b/src/relayController.js index f1e67d7..5928e93 100644 --- a/src/relayController.js +++ b/src/relayController.js @@ -83,6 +83,7 @@ withdrawQueue.process(async function(job, done){ error: 'The note has been spent.' } }) + return } const isKnownRoot = await mixer.methods.isKnownRoot(root).call() if (!isKnownRoot) { @@ -92,6 +93,7 @@ withdrawQueue.process(async function(job, done){ error: 'The merkle root is too old or invalid.' } }) + return } let gas = await mixer.methods.withdraw(proof, ...args).estimateGas({ From 4bc5d341ca542ead6f7018d5495867145d92b766 Mon Sep 17 00:00:00 2001 From: Roman Storm Date: Thu, 19 Dec 2019 01:03:28 -0800 Subject: [PATCH 04/12] add tokens --- config.js | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/config.js b/config.js index 0ac3336..2929571 100644 --- a/config.js +++ b/config.js @@ -28,6 +28,16 @@ module.exports = { tokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', decimals: 6 }, + cusdc: { + mixerAddress: { + '5000': undefined, + '50000': undefined, + '100000': undefined, + '500000': undefined + }, + tokenAddress: '0x39AA39c021dfbaE8faC545936693aC917d5E7563', + decimals: 8 + }, eth: { mixerAddress: { '0.1': '0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc', @@ -41,30 +51,40 @@ module.exports = { netId42: { dai: { mixerAddress: { - '100': '0x7832f65F4030113C007538f29AbC6C13241d4478', - '500': undefined, - '1000': undefined, - '5000': undefined + '100': '0xdf2d3cC5F361CF95b3f62c4bB66deFe3FDE47e3D', + '1000': '0xD96291dFa35d180a71964D0894a1Ae54247C4ccD', + '10000': '0xb192794f72EA45e33C3DF6fe212B9c18f6F45AE3', + '100000': undefined }, - tokenAddress: '0x8c158c7e57161dd4d3cb02bf1a3a97fcc78b75fd', + tokenAddress: '0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa', decimals: 18 }, usdc: { mixerAddress: { - '100': '0x42d096a9194a18DAA2d2D95a70D8dA80DeFFB645', - '500': undefined, - '1000': undefined, - '5000': undefined + '100': '0x137E2B6d185018e7f09f6cf175a970e7fC73826C', + '1000': '0xcC7f1633A5068E86E3830e692e3e3f8f520525Af', + '10000': '0x28C8f149a0ab8A9bdB006B8F984fFFCCE52ef5EF', + '100000': undefined }, - tokenAddress: '0x7f5939049c0D7D7dFC484f64600c9306F79a0D3F', + tokenAddress: '0x75B0622Cec14130172EaE9Cf166B92E5C112FaFF', decimals: 6 }, + cusdc: { + mixerAddress: { + '5000': '0xc0648F28ABA385c8a1421Bbf1B59e3c474F89cB0', + '50000': '0x0C53853379c6b1A7B74E0A324AcbDD5Eabd4981D', + '500000': '0xf84016A0E03917cBe700D318EB1b7a53e6e3dEe1', + '5000000': undefined + }, + tokenAddress: '0xcfC9bB230F00bFFDB560fCe2428b4E05F3442E35', + decimals: 8 + }, eth: { mixerAddress: { '0.1': '0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f', '1': '0xD6a6AC46d02253c938B96D12BE439F570227aE8E', '10': '0xe1BE96331391E519471100c3c1528B66B8F4e5a7', - '100': undefined + '100': '0xd037E0Ac98Dab2fCb7E296c69C6e52767Ae5414D' }, decimals: 18 } From 9e2eef492ab1f919d3afc6d6811653e29b9bd810 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 19 Dec 2019 17:29:22 +0300 Subject: [PATCH 05/12] add cDAI and usdt --- config.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/config.js b/config.js index 2929571..9fc3dee 100644 --- a/config.js +++ b/config.js @@ -18,6 +18,17 @@ module.exports = { tokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f', decimals: 18 }, + cdai: { + mixerAddress: { + '5000': undefined, + '50000': undefined, + '500000': undefined, + '5000000': undefined + }, + tokenAddress: '0x5d3a536e4d6dbd6114cc1ead35777bab948e3643', + symbol: 'cDAI', + decimals: 8 + }, usdc: { mixerAddress: { '100': undefined, @@ -46,6 +57,16 @@ module.exports = { '100': undefined }, decimals: 18 + }, + usdt: { + mixerAddress: { + '100': undefined, + '1000': undefined, + '10000': undefined, + '100000': undefined + }, + tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + decimals: 6 } }, netId42: { @@ -59,6 +80,16 @@ module.exports = { tokenAddress: '0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa', decimals: 18 }, + cdai: { + mixerAddress: { + '5000': '0x6Fc9386ABAf83147b3a89C36D422c625F44121C8', + '50000': '0x7182EA067e0f050997444FCb065985Fd677C16b6', + '500000': '0xC22ceFd90fbd1FdEeE554AE6Cc671179BC3b10Ae', + '5000000': undefined + }, + tokenAddress: '0xe7bc397dbd069fc7d0109c0636d06888bb50668c', + decimals: 8 + }, usdc: { mixerAddress: { '100': '0x137E2B6d185018e7f09f6cf175a970e7fC73826C', @@ -87,6 +118,16 @@ module.exports = { '100': '0xd037E0Ac98Dab2fCb7E296c69C6e52767Ae5414D' }, decimals: 18 + }, + usdt: { + mixerAddress: { + '100': '0x327853Da7916a6A0935563FB1919A48843036b42', + '1000': '0x531AA4DF5858EA1d0031Dad16e3274609DE5AcC0', + '10000': '0x0958275F0362cf6f07D21373aEE0cf37dFe415dD', + '100000': undefined + }, + tokenAddress: '0x03c5f29e9296006876d8df210bcffd7ea5db1cf1', + decimals: 6 } } }, From 91b97e027630d2c80fd17cf57326775ce058aa07 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 23 Dec 2019 19:38:44 +0300 Subject: [PATCH 06/12] onchain prices --- .env.example | 2 ++ abis/PriceOracle.abi.json | 33 ++++++++++++++++++++++++++++ config.js | 6 ++++-- package.json | 1 - src/Fetcher.js | 45 +++++++++++++++++++++++++-------------- src/utils.js | 16 ++++++++++---- yarn.lock | 5 ----- 7 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 abis/PriceOracle.abi.json diff --git a/.env.example b/.env.example index 177cd99..459ac8c 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,7 @@ NET_ID=42 RPC_URL=https://kovan.infura.io +# ORACLE_RPC_URL should always point to mainnet +ORACLE_RPC_URL=https://mainnet.infura.io REDIS_URL=redis://127.0.0.1:6379 # without 0x prefix diff --git a/abis/PriceOracle.abi.json b/abis/PriceOracle.abi.json new file mode 100644 index 0000000..ac5be41 --- /dev/null +++ b/abis/PriceOracle.abi.json @@ -0,0 +1,33 @@ +[ + { + "constant": true, + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "fromTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "oneUnitAmounts", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "parts", + "type": "uint256[]" + } + ], + "name": "getPricesInETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "prices", + "type": "uint256[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/config.js b/config.js index 9fc3dee..ed4b53c 100644 --- a/config.js +++ b/config.js @@ -1,10 +1,12 @@ require('dotenv').config() module.exports = { - version: '1.0', + version: '1.1', netId: Number(process.env.NET_ID) || 42, redisUrl: process.env.REDIS_URL, - rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/v3/a3f4d001c1fc4a359ea70dd27fd9cb51', + rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/', + oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/', + oracleAddress: '0x5c4c5622670423b8ee5F3A02F505D139fbAfb618', privateKey: process.env.PRIVATE_KEY, mixers: { netId1: { diff --git a/package.json b/package.json index ca86941..12827b6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "license": "MIT", "dependencies": { "bull": "^3.12.1", - "coingecko-api": "^1.0.6", "dotenv": "^8.2.0", "express": "^4.17.1", "ioredis": "^4.14.1", diff --git a/src/Fetcher.js b/src/Fetcher.js index 5e68a5e..08bc1f1 100644 --- a/src/Fetcher.js +++ b/src/Fetcher.js @@ -1,37 +1,50 @@ -const CoinGecko = require('coingecko-api') const fetch = require('node-fetch') -const { toWei } = require('web3-utils') -const { gasOracleUrls, defaultGasPrice } = require('../config') -const { getMainnetTokens } = require('./utils') +const Web3 = require('Web3') +const { gasOracleUrls, defaultGasPrice, oracleRpcUrl, oracleAddress } = require('../config') +const { getArgsForOracle } = require('./utils') const { redisClient } = require('./redis') +const priceOracleABI = require('../abis/PriceOracle.abi.json') class Fetcher { constructor(web3) { this.web3 = web3 + this.oracleWeb3 = new Web3(oracleRpcUrl) + this.oracle = new this.oracleWeb3.eth.Contract(priceOracleABI, oracleAddress) this.ethPrices = { - dai: '6700000000000000' // 0.0067 + dai: '6700000000000000', // 0.0067 + cdai: '157380000000000', + cusdc: '164630000000000', + usdc: '7878580000000000', + usdt: '7864940000000000' } + this.tokenAddresses + this.oneUintAmount + this.parts + this.currencyLookup this.gasPrices = { fast: defaultGasPrice } + + const { tokenAddresses, oneUintAmount, parts, currencyLookup } = getArgsForOracle() + this.tokenAddresses = tokenAddresses + this.oneUintAmount = oneUintAmount + this.parts = parts + this.currencyLookup = currencyLookup } async fetchPrices() { - const { tokenAddresses, currencyLookup } = getMainnetTokens() try { - const CoinGeckoClient = new CoinGecko() - const price = await CoinGeckoClient.simple.fetchTokenPrice({ - contract_addresses: tokenAddresses, - vs_currencies: 'eth', - assetPlatform: 'ethereum' - }) - this.ethPrices = Object.entries(price.data).reduce((acc, token) => { - if (token[1].eth) { - acc[currencyLookup[token[0]]] = toWei(token[1].eth.toString()) - } + let prices = await this.oracle.methods.getPricesInETH( + this.tokenAddresses, + this.oneUintAmount, + this.parts + ).call() + this.ethPrices = prices.reduce((acc, price, i) => { + acc[this.currencyLookup[this.tokenAddresses[i]]] = price return acc }, {}) setTimeout(() => this.fetchPrices(), 1000 * 30) } catch(e) { + console.error('fetchPrices', e) setTimeout(() => this.fetchPrices(), 1000 * 30) } } diff --git a/src/utils.js b/src/utils.js index fe6265d..6dd1a63 100644 --- a/src/utils.js +++ b/src/utils.js @@ -138,21 +138,29 @@ function isEnoughFee({ gas, gasPrices, currency, amount, refund, ethPrices, fee return { isEnough: true } } -function getMainnetTokens() { +function getArgsForOracle() { const tokens = mixers['netId1'] const tokenAddresses = [] + const oneUintAmount = [] + const parts = [] // this is probably should be removed const currencyLookup = {} Object.entries(tokens).map(([currency, data]) => { if (currency !== 'eth') { tokenAddresses.push(data.tokenAddress) - currencyLookup[data.tokenAddress.toLowerCase()] = currency + oneUintAmount.push( + toBN('10') + .pow(toBN(data.decimals.toString())) + .toString() + ) + parts.push('1') + currencyLookup[data.tokenAddress] = currency } }) - return { tokenAddresses, currencyLookup } + return { tokenAddresses, oneUintAmount, parts, currencyLookup } } function getMixers() { return mixers[`netId${netId}`] } -module.exports = { isValidProof, isValidArgs, sleep, isKnownContract, isEnoughFee, getMixers, getMainnetTokens } +module.exports = { isValidProof, isValidArgs, sleep, isKnownContract, isEnoughFee, getMixers, getArgsForOracle } diff --git a/yarn.lock b/yarn.lock index 8afa542..a5fc4fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -477,11 +477,6 @@ cluster-key-slot@^1.1.0: resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== -coingecko-api@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/coingecko-api/-/coingecko-api-1.0.6.tgz#ecc42eb96fb1cc721e319c3d06244a642394ab34" - integrity sha512-6oJ3aB9F4AlsHQQ4F5N9753FGmMQrr12aGJl79KSfdNOFJ7wvFLSqsBoOBzgYJEab3hJ7cCWnmo2dMJs6KsA3A== - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" From 525ca3bb84b26fd79a3e6dc3de491bdbd51c542c Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 23 Dec 2019 22:40:08 +0300 Subject: [PATCH 07/12] removed parts param --- abis/PriceOracle.abi.json | 7 +------ config.js | 2 +- src/Fetcher.js | 12 ++++-------- src/utils.js | 4 +--- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/abis/PriceOracle.abi.json b/abis/PriceOracle.abi.json index ac5be41..5b9f897 100644 --- a/abis/PriceOracle.abi.json +++ b/abis/PriceOracle.abi.json @@ -11,11 +11,6 @@ "internalType": "uint256[]", "name": "oneUnitAmounts", "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "parts", - "type": "uint256[]" } ], "name": "getPricesInETH", @@ -30,4 +25,4 @@ "stateMutability": "view", "type": "function" } -] +] \ No newline at end of file diff --git a/config.js b/config.js index ed4b53c..0c88d0c 100644 --- a/config.js +++ b/config.js @@ -6,7 +6,7 @@ module.exports = { redisUrl: process.env.REDIS_URL, rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/', oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/', - oracleAddress: '0x5c4c5622670423b8ee5F3A02F505D139fbAfb618', + oracleAddress: '0xB5eE7907FF5f4c1FC9086Fc117E6c397431F39ad', privateKey: process.env.PRIVATE_KEY, mixers: { netId1: { diff --git a/src/Fetcher.js b/src/Fetcher.js index 08bc1f1..240acfa 100644 --- a/src/Fetcher.js +++ b/src/Fetcher.js @@ -19,25 +19,21 @@ class Fetcher { } this.tokenAddresses this.oneUintAmount - this.parts this.currencyLookup this.gasPrices = { fast: defaultGasPrice } - const { tokenAddresses, oneUintAmount, parts, currencyLookup } = getArgsForOracle() + const { tokenAddresses, oneUintAmount, currencyLookup } = getArgsForOracle() this.tokenAddresses = tokenAddresses this.oneUintAmount = oneUintAmount - this.parts = parts this.currencyLookup = currencyLookup } async fetchPrices() { try { - let prices = await this.oracle.methods.getPricesInETH( - this.tokenAddresses, - this.oneUintAmount, - this.parts - ).call() + let prices = await this.oracle.methods + .getPricesInETH(this.tokenAddresses, this.oneUintAmount) + .call() this.ethPrices = prices.reduce((acc, price, i) => { acc[this.currencyLookup[this.tokenAddresses[i]]] = price return acc diff --git a/src/utils.js b/src/utils.js index 6dd1a63..d788a30 100644 --- a/src/utils.js +++ b/src/utils.js @@ -142,7 +142,6 @@ function getArgsForOracle() { const tokens = mixers['netId1'] const tokenAddresses = [] const oneUintAmount = [] - const parts = [] // this is probably should be removed const currencyLookup = {} Object.entries(tokens).map(([currency, data]) => { if (currency !== 'eth') { @@ -152,11 +151,10 @@ function getArgsForOracle() { .pow(toBN(data.decimals.toString())) .toString() ) - parts.push('1') currencyLookup[data.tokenAddress] = currency } }) - return { tokenAddresses, oneUintAmount, parts, currencyLookup } + return { tokenAddresses, oneUintAmount, currencyLookup } } function getMixers() { From ee046adf070f7c1df55ce4a2b76124f187fdf109 Mon Sep 17 00:00:00 2001 From: poma Date: Thu, 26 Dec 2019 00:09:21 +0700 Subject: [PATCH 08/12] fix dependency --- src/Fetcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fetcher.js b/src/Fetcher.js index 240acfa..711bf4e 100644 --- a/src/Fetcher.js +++ b/src/Fetcher.js @@ -1,5 +1,5 @@ const fetch = require('node-fetch') -const Web3 = require('Web3') +const Web3 = require('web3') const { gasOracleUrls, defaultGasPrice, oracleRpcUrl, oracleAddress } = require('../config') const { getArgsForOracle } = require('./utils') const { redisClient } = require('./redis') From 3fb4a0e34c6513e2054d549963b6a4edd650c0a4 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 25 Dec 2019 21:18:00 +0300 Subject: [PATCH 09/12] checksum updates --- config.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config.js b/config.js index 0c88d0c..43c79a3 100644 --- a/config.js +++ b/config.js @@ -17,7 +17,7 @@ module.exports = { '1000': undefined, '5000': undefined }, - tokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f', + tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', decimals: 18 }, cdai: { @@ -27,7 +27,7 @@ module.exports = { '500000': undefined, '5000000': undefined }, - tokenAddress: '0x5d3a536e4d6dbd6114cc1ead35777bab948e3643', + tokenAddress: '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', symbol: 'cDAI', decimals: 8 }, @@ -38,7 +38,7 @@ module.exports = { '1000': undefined, '5000': undefined }, - tokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', decimals: 6 }, cusdc: { @@ -89,7 +89,7 @@ module.exports = { '500000': '0xC22ceFd90fbd1FdEeE554AE6Cc671179BC3b10Ae', '5000000': undefined }, - tokenAddress: '0xe7bc397dbd069fc7d0109c0636d06888bb50668c', + tokenAddress: '0xe7bc397DBd069fC7d0109C0636d06888bb50668c', decimals: 8 }, usdc: { @@ -128,7 +128,7 @@ module.exports = { '10000': '0x0958275F0362cf6f07D21373aEE0cf37dFe415dD', '100000': undefined }, - tokenAddress: '0x03c5f29e9296006876d8df210bcffd7ea5db1cf1', + tokenAddress: '0x03c5F29e9296006876d8DF210BCFfD7EA5Db1Cf1', decimals: 6 } } From 42f67f278248bba7d65d61ccb927a801d8a1a8ec Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 25 Dec 2019 21:52:49 +0300 Subject: [PATCH 10/12] new addreses for mainnet --- config.js | 85 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/config.js b/config.js index 43c79a3..2f1a68d 100644 --- a/config.js +++ b/config.js @@ -10,21 +10,32 @@ module.exports = { privateKey: process.env.PRIVATE_KEY, mixers: { netId1: { + eth: { + mixerAddress: { + '0.1': '0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc', + '1': '0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936', + '10': '0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF', + '100': '0xA160cdAB225685dA1d56aa342Ad8841c3b53f291' + }, + symbol: 'ETH', + decimals: 18 + }, dai: { mixerAddress: { '100': '0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3', - '500': undefined, - '1000': undefined, - '5000': undefined + '1000': '0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144', + '10000': '0xF60dD140cFf0706bAE9Cd734Ac3ae76AD9eBC32A', + '100000': undefined }, tokenAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + symbol: 'DAI', decimals: 18 }, cdai: { mixerAddress: { - '5000': undefined, - '50000': undefined, - '500000': undefined, + '5000': '0x22aaA7720ddd5388A3c0A3333430953C68f1849b', + '50000': '0xBA214C1c1928a32Bffe790263E38B4Af9bFCD659', + '500000': '0xb1C8094B234DcE6e03f10a5b673c1d8C69739A00', '5000000': undefined }, tokenAddress: '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', @@ -33,45 +44,49 @@ module.exports = { }, usdc: { mixerAddress: { - '100': undefined, - '500': undefined, - '1000': undefined, - '5000': undefined + '100': '0xd96f2B1c14Db8458374d9Aca76E26c3D18364307', + '1000': '0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D', + '10000': '0xD691F27f38B395864Ea86CfC7253969B409c362d', + '100000': undefined }, tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', decimals: 6 }, cusdc: { mixerAddress: { - '5000': undefined, - '50000': undefined, - '100000': undefined, - '500000': undefined + '5000': '0xaEaaC358560e11f52454D997AAFF2c5731B6f8a6', + '50000': '0x1356c899D8C9467C7f71C195612F8A395aBf2f0a', + '500000': '0xA60C772958a3eD56c1F15dD055bA37AC8e523a0D', + '5000000': undefined }, tokenAddress: '0x39AA39c021dfbaE8faC545936693aC917d5E7563', + symbol: 'cUSDC', decimals: 8 }, - eth: { - mixerAddress: { - '0.1': '0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc', - '1': '0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936', - '10': '0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF', - '100': undefined - }, - decimals: 18 - }, usdt: { mixerAddress: { - '100': undefined, - '1000': undefined, - '10000': undefined, - '100000': undefined + '100': '0x169AD27A470D064DEDE56a2D3ff727986b15D52B', + '1000': '0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f', + '10000': '0xF67721A2D8F736E75a49FdD7FAd2e31D8676542a', + '100000': '0x9AD122c22B14202B4490eDAf288FDb3C7cb3ff5E' }, tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + symbol: 'USDT', decimals: 6 } }, netId42: { + eth: { + mixerAddress: { + '0.1': '0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f', + '1': '0xD6a6AC46d02253c938B96D12BE439F570227aE8E', + '10': '0xe1BE96331391E519471100c3c1528B66B8F4e5a7', + '100': '0xd037E0Ac98Dab2fCb7E296c69C6e52767Ae5414D' + }, + symbol: 'ETH', + decimals: 18 + }, dai: { mixerAddress: { '100': '0xdf2d3cC5F361CF95b3f62c4bB66deFe3FDE47e3D', @@ -80,6 +95,7 @@ module.exports = { '100000': undefined }, tokenAddress: '0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa', + symbol: 'DAI', decimals: 18 }, cdai: { @@ -90,6 +106,7 @@ module.exports = { '5000000': undefined }, tokenAddress: '0xe7bc397DBd069fC7d0109C0636d06888bb50668c', + symbol: 'cDAI', decimals: 8 }, usdc: { @@ -100,6 +117,7 @@ module.exports = { '100000': undefined }, tokenAddress: '0x75B0622Cec14130172EaE9Cf166B92E5C112FaFF', + symbol: 'USDC', decimals: 6 }, cusdc: { @@ -110,25 +128,18 @@ module.exports = { '5000000': undefined }, tokenAddress: '0xcfC9bB230F00bFFDB560fCe2428b4E05F3442E35', + symbol: 'cUSDC', decimals: 8 }, - eth: { - mixerAddress: { - '0.1': '0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f', - '1': '0xD6a6AC46d02253c938B96D12BE439F570227aE8E', - '10': '0xe1BE96331391E519471100c3c1528B66B8F4e5a7', - '100': '0xd037E0Ac98Dab2fCb7E296c69C6e52767Ae5414D' - }, - decimals: 18 - }, usdt: { mixerAddress: { '100': '0x327853Da7916a6A0935563FB1919A48843036b42', '1000': '0x531AA4DF5858EA1d0031Dad16e3274609DE5AcC0', '10000': '0x0958275F0362cf6f07D21373aEE0cf37dFe415dD', - '100000': undefined + '100000': '0x14aEd24B67EaF3FF28503eB92aeb217C47514364' }, tokenAddress: '0x03c5F29e9296006876d8DF210BCFfD7EA5Db1Cf1', + symbol: 'USDT', decimals: 6 } } From 0dd0823423c1fcdaa0fd59fd38585b74105a3b9e Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 25 Dec 2019 22:23:53 +0300 Subject: [PATCH 11/12] fix low nonce bug --- src/relayController.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/relayController.js b/src/relayController.js index 5928e93..fe89857 100644 --- a/src/relayController.js +++ b/src/relayController.js @@ -152,7 +152,8 @@ async function sendTx(tx, done, retryAttempt = 1) { }).on('error', async function(e){ console.log('error', e.message) if(e.message === 'Returned error: Transaction gas price supplied is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce.' - || e.message === 'Returned error: Transaction nonce is too low. Try incrementing the nonce.') { + || e.message === 'Returned error: Transaction nonce is too low. Try incrementing the nonce.' + || e.message === 'Returned error: nonce too low') { console.log('nonce too low, retrying') if(retryAttempt <= 10) { retryAttempt++ From 44909ef1882532bef0bc4b2af4c6e5fb62063e7a Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 25 Dec 2019 22:29:38 +0300 Subject: [PATCH 12/12] fix replacement bug --- config.js | 2 +- src/relayController.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config.js b/config.js index 2f1a68d..98c5b7d 100644 --- a/config.js +++ b/config.js @@ -1,7 +1,7 @@ require('dotenv').config() module.exports = { - version: '1.1', + version: '1.2', netId: Number(process.env.NET_ID) || 42, redisUrl: process.env.REDIS_URL, rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/', diff --git a/src/relayController.js b/src/relayController.js index fe89857..7b10728 100644 --- a/src/relayController.js +++ b/src/relayController.js @@ -153,7 +153,8 @@ async function sendTx(tx, done, retryAttempt = 1) { console.log('error', e.message) if(e.message === 'Returned error: Transaction gas price supplied is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce.' || e.message === 'Returned error: Transaction nonce is too low. Try incrementing the nonce.' - || e.message === 'Returned error: nonce too low') { + || e.message === 'Returned error: nonce too low' + || e.message === 'Returned error: replacement transaction underpriced') { console.log('nonce too low, retrying') if(retryAttempt <= 10) { retryAttempt++