Calculate withdrawal gas & token prices via @tornado/tornado-oracles
This commit is contained in:
parent
40c55b3e7c
commit
67c0782794
@ -1,6 +1,6 @@
|
|||||||
NET_ID=1
|
NET_ID=1
|
||||||
HTTP_RPC_URL=https://api.securerpc.com/v1
|
HTTP_RPC_URL=https://api.securerpc.com/v1
|
||||||
# WS_RPC_URL=wss://mainnet.infura.io/ws/v3/
|
WS_RPC_URL=wss://mainnet.infura.io/ws/v3/
|
||||||
# ORACLE_RPC_URL should always point to the mainnet
|
# ORACLE_RPC_URL should always point to the mainnet
|
||||||
ORACLE_RPC_URL=https://api.securerpc.com/v1
|
ORACLE_RPC_URL=https://api.securerpc.com/v1
|
||||||
REDIS_URL=redis://127.0.0.1:6379
|
REDIS_URL=redis://127.0.0.1:6379
|
||||||
@ -13,7 +13,7 @@ APP_PORT=8000
|
|||||||
# without 0x prefix
|
# without 0x prefix
|
||||||
PRIVATE_KEY=
|
PRIVATE_KEY=
|
||||||
# 0.05 means 0.05%
|
# 0.05 means 0.05%
|
||||||
REGULAR_TORNADO_WITHDRAW_FEE=0.35
|
RELAYER_FEE=0.4
|
||||||
MINING_SERVICE_FEE=0.05
|
MINING_SERVICE_FEE=0.05
|
||||||
REWARD_ACCOUNT=
|
REWARD_ACCOUNT=
|
||||||
CONFIRMATIONS=4
|
CONFIRMATIONS=4
|
||||||
|
@ -1,181 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{ "internalType": "contract MultiWrapper", "name": "_multiWrapper", "type": "address" },
|
|
||||||
{ "internalType": "contract IOracle[]", "name": "existingOracles", "type": "address[]" },
|
|
||||||
{ "internalType": "enum OffchainOracle.OracleType[]", "name": "oracleTypes", "type": "uint8[]" },
|
|
||||||
{ "internalType": "contract IERC20[]", "name": "existingConnectors", "type": "address[]" },
|
|
||||||
{ "internalType": "contract IERC20", "name": "wBase", "type": "address" }
|
|
||||||
],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "constructor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{ "indexed": false, "internalType": "contract IERC20", "name": "connector", "type": "address" }
|
|
||||||
],
|
|
||||||
"name": "ConnectorAdded",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{ "indexed": false, "internalType": "contract IERC20", "name": "connector", "type": "address" }
|
|
||||||
],
|
|
||||||
"name": "ConnectorRemoved",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{ "indexed": false, "internalType": "contract MultiWrapper", "name": "multiWrapper", "type": "address" }
|
|
||||||
],
|
|
||||||
"name": "MultiWrapperUpdated",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{ "indexed": false, "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
|
||||||
{
|
|
||||||
"indexed": false,
|
|
||||||
"internalType": "enum OffchainOracle.OracleType",
|
|
||||||
"name": "oracleType",
|
|
||||||
"type": "uint8"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "OracleAdded",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{ "indexed": false, "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
|
||||||
{
|
|
||||||
"indexed": false,
|
|
||||||
"internalType": "enum OffchainOracle.OracleType",
|
|
||||||
"name": "oracleType",
|
|
||||||
"type": "uint8"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "OracleRemoved",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" },
|
|
||||||
{ "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }
|
|
||||||
],
|
|
||||||
"name": "OwnershipTransferred",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [{ "internalType": "contract IERC20", "name": "connector", "type": "address" }],
|
|
||||||
"name": "addConnector",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{ "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
|
||||||
{ "internalType": "enum OffchainOracle.OracleType", "name": "oracleKind", "type": "uint8" }
|
|
||||||
],
|
|
||||||
"name": "addOracle",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "connectors",
|
|
||||||
"outputs": [{ "internalType": "contract IERC20[]", "name": "allConnectors", "type": "address[]" }],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{ "internalType": "contract IERC20", "name": "srcToken", "type": "address" },
|
|
||||||
{ "internalType": "contract IERC20", "name": "dstToken", "type": "address" },
|
|
||||||
{ "internalType": "bool", "name": "useWrappers", "type": "bool" }
|
|
||||||
],
|
|
||||||
"name": "getRate",
|
|
||||||
"outputs": [{ "internalType": "uint256", "name": "weightedRate", "type": "uint256" }],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{ "internalType": "contract IERC20", "name": "srcToken", "type": "address" },
|
|
||||||
{ "internalType": "bool", "name": "useSrcWrappers", "type": "bool" }
|
|
||||||
],
|
|
||||||
"name": "getRateToEth",
|
|
||||||
"outputs": [{ "internalType": "uint256", "name": "weightedRate", "type": "uint256" }],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "multiWrapper",
|
|
||||||
"outputs": [{ "internalType": "contract MultiWrapper", "name": "", "type": "address" }],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "oracles",
|
|
||||||
"outputs": [
|
|
||||||
{ "internalType": "contract IOracle[]", "name": "allOracles", "type": "address[]" },
|
|
||||||
{ "internalType": "enum OffchainOracle.OracleType[]", "name": "oracleTypes", "type": "uint8[]" }
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "owner",
|
|
||||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [{ "internalType": "contract IERC20", "name": "connector", "type": "address" }],
|
|
||||||
"name": "removeConnector",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{ "internalType": "contract IOracle", "name": "oracle", "type": "address" },
|
|
||||||
{ "internalType": "enum OffchainOracle.OracleType", "name": "oracleKind", "type": "uint8" }
|
|
||||||
],
|
|
||||||
"name": "removeOracle",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "renounceOwnership",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [{ "internalType": "contract MultiWrapper", "name": "_multiWrapper", "type": "address" }],
|
|
||||||
"name": "setMultiWrapper",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }],
|
|
||||||
"name": "transferOwnership",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
}
|
|
||||||
]
|
|
12
package.json
12
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "relay",
|
"name": "relay",
|
||||||
"version": "5.1.0",
|
"version": "5.2.0",
|
||||||
"description": "Relayer for Tornado.cash privacy solution. https://tornado.cash",
|
"description": "Relayer for Tornado.cash privacy solution.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"server": "node src/server.js",
|
"server": "node src/server.js",
|
||||||
"worker": "node src/worker",
|
"worker": "node src/worker",
|
||||||
@ -16,22 +16,22 @@
|
|||||||
"build": "docker build -t tornadocash/relayer:mainnet-v5 .",
|
"build": "docker build -t tornadocash/relayer:mainnet-v5 .",
|
||||||
"start": "docker-compose up -d redis && concurrently \"yarn server\" \"yarn priceWatcher\" \"yarn treeWatcher\" \"yarn worker\" \"yarn healthWatcher\""
|
"start": "docker-compose up -d redis && concurrently \"yarn server\" \"yarn priceWatcher\" \"yarn treeWatcher\" \"yarn worker\" \"yarn healthWatcher\""
|
||||||
},
|
},
|
||||||
"author": "tornado.cash",
|
"author": "Tornado Cash team",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"circomlib": "git+https://git.tornado.ws/tornado-packages/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
|
"@tornado/tornado-config": "^2.0.0",
|
||||||
|
"@tornado/tornado-oracles": "^2.1.0",
|
||||||
"ajv": "^6.12.5",
|
"ajv": "^6.12.5",
|
||||||
"async-mutex": "^0.2.4",
|
"async-mutex": "^0.2.4",
|
||||||
"bull": "^3.12.1",
|
"bull": "^3.12.1",
|
||||||
|
"circomlib": "git+https://git.tornado.ws/tornado-packages/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
|
||||||
"concurrently": "^8.2.0",
|
"concurrently": "^8.2.0",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"eth-ens-namehash": "^2.0.8",
|
"eth-ens-namehash": "^2.0.8",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"fixed-merkle-tree": "^0.4.0",
|
"fixed-merkle-tree": "^0.4.0",
|
||||||
"@tornado/gas-price-oracle": "^0.5.3",
|
|
||||||
"ioredis": "^4.14.1",
|
"ioredis": "^4.14.1",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
"torn-token": "1.0.6",
|
|
||||||
"tornado-anonymity-mining": "^2.1.2",
|
"tornado-anonymity-mining": "^2.1.2",
|
||||||
"tx-manager": "^0.4.8",
|
"tx-manager": "^0.4.8",
|
||||||
"uuid": "^8.3.0",
|
"uuid": "^8.3.0",
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
const { jobType } = require('./constants')
|
const { jobType } = require('./constants')
|
||||||
const tornConfig = require('torn-token')
|
const tornConfig = require('@tornado/tornado-config')
|
||||||
module.exports = {
|
module.exports = {
|
||||||
netId: Number(process.env.NET_ID) || 1,
|
netId: Number(process.env.NET_ID) || 1,
|
||||||
redisUrl: process.env.REDIS_URL || 'redis://127.0.0.1:6379',
|
redisUrl: process.env.REDIS_URL || 'redis://127.0.0.1:6379',
|
||||||
httpRpcUrl: process.env.HTTP_RPC_URL,
|
httpRpcUrl: process.env.HTTP_RPC_URL,
|
||||||
wsRpcUrl: process.env.WS_RPC_URL,
|
wsRpcUrl: process.env.WS_RPC_URL,
|
||||||
oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/',
|
oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://api.securerpc.com/v1',
|
||||||
offchainOracleAddress: '0x07D91f5fb9Bf7798734C3f606dB065549F6893bb',
|
|
||||||
aggregatorAddress: process.env.AGGREGATOR,
|
aggregatorAddress: process.env.AGGREGATOR,
|
||||||
minerMerkleTreeHeight: 20,
|
minerMerkleTreeHeight: 20,
|
||||||
privateKey: process.env.PRIVATE_KEY,
|
privateKey: process.env.PRIVATE_KEY,
|
||||||
@ -16,13 +15,10 @@ module.exports = {
|
|||||||
torn: tornConfig,
|
torn: tornConfig,
|
||||||
port: process.env.APP_PORT || 8000,
|
port: process.env.APP_PORT || 8000,
|
||||||
tornadoServiceFee: Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE),
|
tornadoServiceFee: Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE),
|
||||||
miningServiceFee: Number(process.env.MINING_SERVICE_FEE),
|
|
||||||
rewardAccount: process.env.REWARD_ACCOUNT,
|
rewardAccount: process.env.REWARD_ACCOUNT,
|
||||||
governanceAddress: '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
|
governanceAddress: '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
|
||||||
tornadoGoerliProxy: '0x454d870a72e29d5E5697f635128D18077BD04C60',
|
tornadoGoerliProxy: '0x454d870a72e29d5E5697f635128D18077BD04C60',
|
||||||
gasLimits: {
|
gasLimits: {
|
||||||
[jobType.TORNADO_WITHDRAW]: 390000,
|
|
||||||
WITHDRAW_WITH_EXTRA: 700000,
|
|
||||||
[jobType.MINING_REWARD]: 455000,
|
[jobType.MINING_REWARD]: 455000,
|
||||||
[jobType.MINING_WITHDRAW]: 400000,
|
[jobType.MINING_WITHDRAW]: 400000,
|
||||||
},
|
},
|
||||||
|
@ -1,41 +1,17 @@
|
|||||||
const { offchainOracleAddress } = require('./config')
|
const { setSafeInterval, RelayerError, logRelayerError } = require('./utils')
|
||||||
const {
|
|
||||||
getArgsForOracle,
|
|
||||||
setSafeInterval,
|
|
||||||
toChecksumAddress,
|
|
||||||
toBN,
|
|
||||||
RelayerError,
|
|
||||||
logRelayerError,
|
|
||||||
} = require('./utils')
|
|
||||||
const { redis } = require('./modules/redis')
|
const { redis } = require('./modules/redis')
|
||||||
const web3 = require('./modules/web3')('oracle')
|
const { TokenPriceOracle } = require('@tornado/tornado-oracles')
|
||||||
|
const { oracleRpcUrl } = require('./config')
|
||||||
|
|
||||||
const offchainOracleABI = require('../abis/OffchainOracle.abi.json')
|
const priceOracle = new TokenPriceOracle(oracleRpcUrl)
|
||||||
|
|
||||||
const offchainOracle = new web3.eth.Contract(offchainOracleABI, offchainOracleAddress)
|
|
||||||
const { tokenAddresses, oneUintAmount, currencyLookup } = getArgsForOracle()
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
const ethPrices = {}
|
const ethPrices = await priceOracle.fetchPrices()
|
||||||
for (let i = 0; i < tokenAddresses.length; i++) {
|
|
||||||
try {
|
|
||||||
const isWrap =
|
|
||||||
toChecksumAddress(tokenAddresses[i]) ===
|
|
||||||
toChecksumAddress('0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643')
|
|
||||||
|
|
||||||
const price = await offchainOracle.methods.getRateToEth(tokenAddresses[i], isWrap).call()
|
|
||||||
const numerator = toBN(oneUintAmount[i])
|
|
||||||
const denominator = toBN(10).pow(toBN(18)) // eth decimals
|
|
||||||
const priceFormatted = toBN(price).mul(numerator).div(denominator)
|
|
||||||
ethPrices[currencyLookup[tokenAddresses[i]]] = priceFormatted.toString()
|
|
||||||
} catch (e) {
|
|
||||||
console.error('cant get price of ', tokenAddresses[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Object.values(ethPrices).length) {
|
if (!Object.values(ethPrices).length) {
|
||||||
throw new RelayerError('Can`t update prices', 1)
|
throw new RelayerError('Can`t update prices', 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
await redis.hmset('prices', ethPrices)
|
await redis.hmset('prices', ethPrices)
|
||||||
console.log('Wrote following prices to redis', ethPrices)
|
console.log('Wrote following prices to redis', ethPrices)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
29
src/utils.js
29
src/utils.js
@ -2,16 +2,8 @@ const { instances, netId } = require('./config')
|
|||||||
const { poseidon } = require('circomlib')
|
const { poseidon } = require('circomlib')
|
||||||
const { toBN, toChecksumAddress, BN, fromWei, isAddress, toWei, toHex } = require('web3-utils')
|
const { toBN, toChecksumAddress, BN, fromWei, isAddress, toWei, toHex } = require('web3-utils')
|
||||||
|
|
||||||
const TOKENS = {
|
|
||||||
torn: {
|
|
||||||
tokenAddress: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
|
|
||||||
symbol: 'TORN',
|
|
||||||
decimals: 18,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const addressMap = new Map()
|
const addressMap = new Map()
|
||||||
const instance = instances[`netId${netId}`]
|
const instance = instances[netId]
|
||||||
|
|
||||||
for (const [currency, { instanceAddress, symbol, decimals }] of Object.entries(instance)) {
|
for (const [currency, { instanceAddress, symbol, decimals }] of Object.entries(instance)) {
|
||||||
Object.entries(instanceAddress).forEach(([amount, address]) =>
|
Object.entries(instanceAddress).forEach(([amount, address]) =>
|
||||||
@ -61,24 +53,6 @@ function when(source, event) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArgsForOracle() {
|
|
||||||
const tokens = {
|
|
||||||
...instances.netId1,
|
|
||||||
...TOKENS,
|
|
||||||
}
|
|
||||||
const tokenAddresses = []
|
|
||||||
const oneUintAmount = []
|
|
||||||
const currencyLookup = {}
|
|
||||||
Object.entries(tokens).map(([currency, data]) => {
|
|
||||||
if (currency !== 'eth') {
|
|
||||||
tokenAddresses.push(data.tokenAddress)
|
|
||||||
oneUintAmount.push(toBN('10').pow(toBN(data.decimals.toString())).toString())
|
|
||||||
currencyLookup[data.tokenAddress] = currency
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return { tokenAddresses, oneUintAmount, currencyLookup }
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromDecimals(value, decimals) {
|
function fromDecimals(value, decimals) {
|
||||||
value = value.toString()
|
value = value.toString()
|
||||||
let ether = value.toString()
|
let ether = value.toString()
|
||||||
@ -155,7 +129,6 @@ module.exports = {
|
|||||||
poseidonHash2,
|
poseidonHash2,
|
||||||
sleep,
|
sleep,
|
||||||
when,
|
when,
|
||||||
getArgsForOracle,
|
|
||||||
fromDecimals,
|
fromDecimals,
|
||||||
toBN,
|
toBN,
|
||||||
toChecksumAddress,
|
toChecksumAddress,
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const MerkleTree = require('fixed-merkle-tree')
|
const MerkleTree = require('fixed-merkle-tree')
|
||||||
const { GasPriceOracle } = require('@tornado/gas-price-oracle')
|
|
||||||
const { Utils, Controller } = require('tornado-anonymity-mining')
|
const { Utils, Controller } = require('tornado-anonymity-mining')
|
||||||
|
const { TornadoFeeOracleV5 } = require('@tornado/tornado-oracles')
|
||||||
const swapABI = require('../abis/swap.abi.json')
|
const swapABI = require('../abis/swap.abi.json')
|
||||||
const miningABI = require('../abis/mining.abi.json')
|
const miningABI = require('../abis/mining.abi.json')
|
||||||
const tornadoABI = require('../abis/tornadoABI.json')
|
const tornadoABI = require('../abis/tornadoABI.json')
|
||||||
@ -47,7 +46,7 @@ let txManager
|
|||||||
let controller
|
let controller
|
||||||
let swap
|
let swap
|
||||||
let minerContract
|
let minerContract
|
||||||
let gasPriceOracle
|
const feeOracle = new TornadoFeeOracleV5(netId, oracleRpcUrl)
|
||||||
|
|
||||||
async function fetchTree() {
|
async function fetchTree() {
|
||||||
const elements = await redis.get('tree:elements')
|
const elements = await redis.get('tree:elements')
|
||||||
@ -94,12 +93,7 @@ async function start() {
|
|||||||
BASE_FEE_RESERVE_PERCENTAGE: baseFeeReserve,
|
BASE_FEE_RESERVE_PERCENTAGE: baseFeeReserve,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
gasPriceOracle = new GasPriceOracle({
|
|
||||||
defaultRpc: oracleRpcUrl,
|
|
||||||
minPriority: 2,
|
|
||||||
percentile: 5,
|
|
||||||
blocksCount: 20,
|
|
||||||
})
|
|
||||||
swap = new web3.eth.Contract(swapABI, await resolver.resolve(torn.rewardSwap.address))
|
swap = new web3.eth.Contract(swapABI, await resolver.resolve(torn.rewardSwap.address))
|
||||||
minerContract = new web3.eth.Contract(miningABI, await resolver.resolve(torn.miningV2.address))
|
minerContract = new web3.eth.Contract(miningABI, await resolver.resolve(torn.miningV2.address))
|
||||||
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
||||||
@ -125,37 +119,6 @@ function checkFee({ data }, gasInfo) {
|
|||||||
return checkMiningFee(data)
|
return checkMiningFee(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getGasPrice() {
|
|
||||||
try {
|
|
||||||
const { maxFeePerGas, gasPrice } = await gasPriceOracle.getTxGasParams({
|
|
||||||
legacySpeed: 'fast',
|
|
||||||
bumpPercent: 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
return toBN(maxFeePerGas || gasPrice)
|
|
||||||
} catch (e) {
|
|
||||||
const block = await web3.eth.getBlock('latest')
|
|
||||||
|
|
||||||
if (block && block.baseFeePerGas) {
|
|
||||||
return toBN(block.baseFeePerGas)
|
|
||||||
}
|
|
||||||
|
|
||||||
const gasPrice = await web3.eth.getGasPrice()
|
|
||||||
return toBN(gasPrice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function estimateWithdrawalGasLimit(tx) {
|
|
||||||
try {
|
|
||||||
const fetchedGasLimit = await web3.eth.estimateGas(tx)
|
|
||||||
const bumped = Math.floor(fetchedGasLimit * 1.2)
|
|
||||||
return bumped
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Estimation error: ', e)
|
|
||||||
return gasLimits[jobType.TORNADO_WITHDRAW]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkTornadoFee({ args, contract }, { gasLimit, gasPrice }) {
|
async function checkTornadoFee({ args, contract }, { gasLimit, gasPrice }) {
|
||||||
const { currency, amount, decimals } = getInstance(contract)
|
const { currency, amount, decimals } = getInstance(contract)
|
||||||
const [fee, refund] = [args[4], args[5]].map(toBN)
|
const [fee, refund] = [args[4], args[5]].map(toBN)
|
||||||
@ -197,12 +160,12 @@ async function checkTornadoFee({ args, contract }, { gasLimit, gasPrice }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function checkMiningFee({ args }) {
|
async function checkMiningFee({ args }) {
|
||||||
const gasPrice = await getGasPrice()
|
const gasPrice = await feeOracle.getGasPrice()
|
||||||
const ethPrice = await redis.hget('prices', 'torn')
|
const ethPrice = await redis.hget('prices', 'torn')
|
||||||
const isMiningReward = currentJob.data.type === jobType.MINING_REWARD
|
const isMiningReward = currentJob.data.type === jobType.MINING_REWARD
|
||||||
const providedFee = isMiningReward ? toBN(args.fee) : toBN(args.extData.fee)
|
const providedFee = isMiningReward ? toBN(args.fee) : toBN(args.extData.fee)
|
||||||
|
|
||||||
const expense = gasPrice.mul(toBN(gasLimits[currentJob.data.type]))
|
const expense = toBN(gasPrice).mul(toBN(gasLimits[currentJob.data.type]))
|
||||||
const expenseInTorn = expense.mul(toBN(1e18)).div(toBN(ethPrice))
|
const expenseInTorn = expense.mul(toBN(1e18)).div(toBN(ethPrice))
|
||||||
// todo make aggregator for ethPrices and rewardSwap data
|
// todo make aggregator for ethPrices and rewardSwap data
|
||||||
const balance = await swap.methods.tornVirtualBalance().call()
|
const balance = await swap.methods.tornVirtualBalance().call()
|
||||||
@ -259,17 +222,15 @@ async function getTxObject({ data }) {
|
|||||||
calldata = contract.methods.withdraw(data.proof, ...data.args).encodeABI()
|
calldata = contract.methods.withdraw(data.proof, ...data.args).encodeABI()
|
||||||
}
|
}
|
||||||
|
|
||||||
const gasPrice = await getGasPrice()
|
|
||||||
const incompleteTx = {
|
const incompleteTx = {
|
||||||
value: data.args[5],
|
value: data.args[5],
|
||||||
from: txManager.address, // Required, because without it relayerRegistry.burn will fail, because msg.sender is not relayer
|
from: txManager.address, // Required, because without it relayerRegistry.burn will fail, because msg.sender is not relayer
|
||||||
to: contract._address,
|
to: contract._address,
|
||||||
data: calldata,
|
data: calldata,
|
||||||
gasPrice: toHex(gasPrice),
|
|
||||||
}
|
}
|
||||||
const gasLimit = await estimateWithdrawalGasLimit(incompleteTx)
|
const { gasLimit, gasPrice } = await feeOracle.getGasParams(incompleteTx, 'relayer_withdrawal')
|
||||||
|
|
||||||
return Object.assign(incompleteTx, { gasLimit })
|
return Object.assign(incompleteTx, { gasLimit, gasPrice })
|
||||||
} else {
|
} else {
|
||||||
const method = data.type === jobType.MINING_REWARD ? 'reward' : 'withdraw'
|
const method = data.type === jobType.MINING_REWARD ? 'reward' : 'withdraw'
|
||||||
const calldata = minerContract.methods[method](data.proof, data.args).encodeABI()
|
const calldata = minerContract.methods[method](data.proof, data.args).encodeABI()
|
||||||
|
40
yarn.lock
40
yarn.lock
@ -409,7 +409,7 @@
|
|||||||
fastfile "0.0.19"
|
fastfile "0.0.19"
|
||||||
ffjavascript "^0.2.30"
|
ffjavascript "^0.2.30"
|
||||||
|
|
||||||
"@openzeppelin/contracts@^3.1.0", "@openzeppelin/contracts@^3.4.0":
|
"@openzeppelin/contracts@^3.4.0":
|
||||||
version "3.4.2"
|
version "3.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527"
|
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527"
|
||||||
integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA==
|
integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA==
|
||||||
@ -456,6 +456,22 @@
|
|||||||
bignumber.js "^9.0.0"
|
bignumber.js "^9.0.0"
|
||||||
node-cache "^5.1.2"
|
node-cache "^5.1.2"
|
||||||
|
|
||||||
|
"@tornado/tornado-config@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ftornado-config/-/2.0.0/tornado-config-2.0.0.tgz#52bbc179ecb2385f71b4d56e060b68e7dd6fb8b4"
|
||||||
|
integrity sha512-7EkpWNfEm34VEOrbLnPpvd/aUJYnA1L+6/qx2fZ/AfmuJFkjSZ18Z4jvVGNY7ktKIhTu3/Tbze+9l3eNueCNIA==
|
||||||
|
|
||||||
|
"@tornado/tornado-oracles@^2.1.0":
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ftornado-oracles/-/2.1.0/tornado-oracles-2.1.0.tgz#2aa0d8c9288992e6d194d4bb28acb37c2035c453"
|
||||||
|
integrity sha512-Y6FPAGnCvHLWzUnNYgGoOv+X7KY3CF02rRSawataYaLyl+v2ivh7RYZZZ3G/B5hXf+pD3IFeCdm4PDnTNyNe1g==
|
||||||
|
dependencies:
|
||||||
|
"@tornado/gas-price-oracle" "^0.5.3"
|
||||||
|
"@tornado/tornado-config" "^2.0.0"
|
||||||
|
"@types/node" "^20.5.1"
|
||||||
|
bignumber.js "^9.1.1"
|
||||||
|
ethers "5.7"
|
||||||
|
|
||||||
"@types/bn.js@^4.11.3":
|
"@types/bn.js@^4.11.3":
|
||||||
version "4.11.6"
|
version "4.11.6"
|
||||||
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
|
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
|
||||||
@ -502,6 +518,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
|
||||||
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
|
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
|
||||||
|
|
||||||
|
"@types/node@^20.5.1":
|
||||||
|
version "20.5.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.8.tgz#fb171fd22d37ca6e2ea97fde88e6a13ee14bc327"
|
||||||
|
integrity sha512-eajsR9aeljqNhK028VG0Wuw+OaY5LLxYmxeoXynIoE6jannr9/Ucd1LL0hSSoafk5LTYG+FfqsyGt81Q6Zkybw==
|
||||||
|
|
||||||
"@types/pbkdf2@^3.0.0":
|
"@types/pbkdf2@^3.0.0":
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1"
|
resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1"
|
||||||
@ -788,6 +809,11 @@ bignumber.js@^9.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6"
|
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6"
|
||||||
integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==
|
integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==
|
||||||
|
|
||||||
|
bignumber.js@^9.1.1:
|
||||||
|
version "9.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
|
||||||
|
integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==
|
||||||
|
|
||||||
binary-extensions@^2.0.0:
|
binary-extensions@^2.0.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||||
@ -2098,7 +2124,7 @@ ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereum
|
|||||||
ethereum-cryptography "^0.1.3"
|
ethereum-cryptography "^0.1.3"
|
||||||
rlp "^2.2.4"
|
rlp "^2.2.4"
|
||||||
|
|
||||||
ethers@^5.4.6:
|
ethers@5.7, ethers@^5.4.6:
|
||||||
version "5.7.2"
|
version "5.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e"
|
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e"
|
||||||
integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==
|
integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==
|
||||||
@ -4896,16 +4922,6 @@ toidentifier@1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
||||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
||||||
|
|
||||||
torn-token@1.0.6:
|
|
||||||
version "1.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/torn-token/-/torn-token-1.0.6.tgz#66cde5f85b611033918c807b4a8d9d4e5bb3fcfc"
|
|
||||||
integrity sha512-ilCS7fN+JM2O8l1Iw5cEWXyiQQg8GxEeYYvqALJcn5cO6qSpD+xJb3Dji4EHXa1Yu1OBd/19ktWNvUkWNvuAaQ==
|
|
||||||
dependencies:
|
|
||||||
"@openzeppelin/contracts" "^3.1.0"
|
|
||||||
eth-sig-util "^2.5.3"
|
|
||||||
ethereumjs-util "^7.0.3"
|
|
||||||
web3 "^1.2.11"
|
|
||||||
|
|
||||||
tornado-anonymity-mining@^2.1.2:
|
tornado-anonymity-mining@^2.1.2:
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/tornado-anonymity-mining/-/tornado-anonymity-mining-2.1.5.tgz#7dbc7f099ce9667f2cc91fbb7ce8f78663afc4cc"
|
resolved "https://registry.yarnpkg.com/tornado-anonymity-mining/-/tornado-anonymity-mining-2.1.5.tgz#7dbc7f099ce9667f2cc91fbb7ce8f78663afc4cc"
|
||||||
|
Loading…
Reference in New Issue
Block a user