mirror of
https://github.com/tornadocash/tornado-relayer
synced 2024-02-02 15:04:06 +01:00
onchain prices
This commit is contained in:
parent
9e2eef492a
commit
91b97e0276
@ -1,5 +1,7 @@
|
|||||||
NET_ID=42
|
NET_ID=42
|
||||||
RPC_URL=https://kovan.infura.io
|
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
|
REDIS_URL=redis://127.0.0.1:6379
|
||||||
|
|
||||||
# without 0x prefix
|
# without 0x prefix
|
||||||
|
33
abis/PriceOracle.abi.json
Normal file
33
abis/PriceOracle.abi.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
@ -1,10 +1,12 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
version: '1.0',
|
version: '1.1',
|
||||||
netId: Number(process.env.NET_ID) || 42,
|
netId: Number(process.env.NET_ID) || 42,
|
||||||
redisUrl: process.env.REDIS_URL,
|
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,
|
privateKey: process.env.PRIVATE_KEY,
|
||||||
mixers: {
|
mixers: {
|
||||||
netId1: {
|
netId1: {
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bull": "^3.12.1",
|
"bull": "^3.12.1",
|
||||||
"coingecko-api": "^1.0.6",
|
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"ioredis": "^4.14.1",
|
"ioredis": "^4.14.1",
|
||||||
|
@ -1,37 +1,50 @@
|
|||||||
const CoinGecko = require('coingecko-api')
|
|
||||||
const fetch = require('node-fetch')
|
const fetch = require('node-fetch')
|
||||||
const { toWei } = require('web3-utils')
|
const Web3 = require('Web3')
|
||||||
const { gasOracleUrls, defaultGasPrice } = require('../config')
|
const { gasOracleUrls, defaultGasPrice, oracleRpcUrl, oracleAddress } = require('../config')
|
||||||
const { getMainnetTokens } = require('./utils')
|
const { getArgsForOracle } = require('./utils')
|
||||||
const { redisClient } = require('./redis')
|
const { redisClient } = require('./redis')
|
||||||
|
const priceOracleABI = require('../abis/PriceOracle.abi.json')
|
||||||
|
|
||||||
class Fetcher {
|
class Fetcher {
|
||||||
constructor(web3) {
|
constructor(web3) {
|
||||||
this.web3 = web3
|
this.web3 = web3
|
||||||
|
this.oracleWeb3 = new Web3(oracleRpcUrl)
|
||||||
|
this.oracle = new this.oracleWeb3.eth.Contract(priceOracleABI, oracleAddress)
|
||||||
this.ethPrices = {
|
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 = {
|
this.gasPrices = {
|
||||||
fast: defaultGasPrice
|
fast: defaultGasPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { tokenAddresses, oneUintAmount, parts, currencyLookup } = getArgsForOracle()
|
||||||
|
this.tokenAddresses = tokenAddresses
|
||||||
|
this.oneUintAmount = oneUintAmount
|
||||||
|
this.parts = parts
|
||||||
|
this.currencyLookup = currencyLookup
|
||||||
}
|
}
|
||||||
async fetchPrices() {
|
async fetchPrices() {
|
||||||
const { tokenAddresses, currencyLookup } = getMainnetTokens()
|
|
||||||
try {
|
try {
|
||||||
const CoinGeckoClient = new CoinGecko()
|
let prices = await this.oracle.methods.getPricesInETH(
|
||||||
const price = await CoinGeckoClient.simple.fetchTokenPrice({
|
this.tokenAddresses,
|
||||||
contract_addresses: tokenAddresses,
|
this.oneUintAmount,
|
||||||
vs_currencies: 'eth',
|
this.parts
|
||||||
assetPlatform: 'ethereum'
|
).call()
|
||||||
})
|
this.ethPrices = prices.reduce((acc, price, i) => {
|
||||||
this.ethPrices = Object.entries(price.data).reduce((acc, token) => {
|
acc[this.currencyLookup[this.tokenAddresses[i]]] = price
|
||||||
if (token[1].eth) {
|
|
||||||
acc[currencyLookup[token[0]]] = toWei(token[1].eth.toString())
|
|
||||||
}
|
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
setTimeout(() => this.fetchPrices(), 1000 * 30)
|
setTimeout(() => this.fetchPrices(), 1000 * 30)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
console.error('fetchPrices', e)
|
||||||
setTimeout(() => this.fetchPrices(), 1000 * 30)
|
setTimeout(() => this.fetchPrices(), 1000 * 30)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
src/utils.js
16
src/utils.js
@ -138,21 +138,29 @@ function isEnoughFee({ gas, gasPrices, currency, amount, refund, ethPrices, fee
|
|||||||
return { isEnough: true }
|
return { isEnough: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMainnetTokens() {
|
function getArgsForOracle() {
|
||||||
const tokens = mixers['netId1']
|
const tokens = mixers['netId1']
|
||||||
const tokenAddresses = []
|
const tokenAddresses = []
|
||||||
|
const oneUintAmount = []
|
||||||
|
const parts = [] // this is probably should be removed
|
||||||
const currencyLookup = {}
|
const currencyLookup = {}
|
||||||
Object.entries(tokens).map(([currency, data]) => {
|
Object.entries(tokens).map(([currency, data]) => {
|
||||||
if (currency !== 'eth') {
|
if (currency !== 'eth') {
|
||||||
tokenAddresses.push(data.tokenAddress)
|
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() {
|
function getMixers() {
|
||||||
return mixers[`netId${netId}`]
|
return mixers[`netId${netId}`]
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { isValidProof, isValidArgs, sleep, isKnownContract, isEnoughFee, getMixers, getMainnetTokens }
|
module.exports = { isValidProof, isValidArgs, sleep, isKnownContract, isEnoughFee, getMixers, getArgsForOracle }
|
||||||
|
@ -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"
|
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
|
||||||
integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==
|
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:
|
color-convert@^1.9.0:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||||
|
Loading…
Reference in New Issue
Block a user