diff --git a/abis/ERC20.abi.json b/abis/ERC20.abi.json new file mode 100644 index 0000000..7d1e856 --- /dev/null +++ b/abis/ERC20.abi.json @@ -0,0 +1,256 @@ +[ + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "_totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/contracts/factories/index.ts b/contracts/factories/index.ts index 1dabf252..a6cb241 100644 --- a/contracts/factories/index.ts +++ b/contracts/factories/index.ts @@ -1,9 +1,10 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ -export { AggregatorAbi__factory } from './AggregatorAbi__factory'; -export { MulticallAbi__factory } from './MulticallAbi__factory'; -export { OffchainOracleAbi__factory } from './OffchainOracleAbi__factory'; -export { ProxyLightABI__factory } from './ProxyLightABI__factory'; -export { TornadoABI__factory } from './TornadoABI__factory'; -export { TornadoProxyABI__factory } from './TornadoProxyABI__factory'; +export { AggregatorAbi__factory } from "./AggregatorAbi__factory"; +export { ERC20Abi__factory } from "./ERC20Abi__factory"; +export { MulticallAbi__factory } from "./MulticallAbi__factory"; +export { OffchainOracleAbi__factory } from "./OffchainOracleAbi__factory"; +export { ProxyLightABI__factory } from "./ProxyLightABI__factory"; +export { TornadoABI__factory } from "./TornadoABI__factory"; +export { TornadoProxyABI__factory } from "./TornadoProxyABI__factory"; diff --git a/contracts/index.ts b/contracts/index.ts index 3be51a6..9a8054b 100644 --- a/contracts/index.ts +++ b/contracts/index.ts @@ -1,16 +1,18 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ -export type { AggregatorAbi } from './AggregatorAbi'; -export type { MulticallAbi } from './MulticallAbi'; -export type { OffchainOracleAbi } from './OffchainOracleAbi'; -export type { ProxyLightABI } from './ProxyLightABI'; -export type { TornadoABI } from './TornadoABI'; -export type { TornadoProxyABI } from './TornadoProxyABI'; -export * as factories from './factories'; -export { AggregatorAbi__factory } from './factories/AggregatorAbi__factory'; -export { MulticallAbi__factory } from './factories/MulticallAbi__factory'; -export { OffchainOracleAbi__factory } from './factories/OffchainOracleAbi__factory'; -export { ProxyLightABI__factory } from './factories/ProxyLightABI__factory'; -export { TornadoABI__factory } from './factories/TornadoABI__factory'; -export { TornadoProxyABI__factory } from './factories/TornadoProxyABI__factory'; +export type { AggregatorAbi } from "./AggregatorAbi"; +export type { ERC20Abi } from "./ERC20Abi"; +export type { MulticallAbi } from "./MulticallAbi"; +export type { OffchainOracleAbi } from "./OffchainOracleAbi"; +export type { ProxyLightABI } from "./ProxyLightABI"; +export type { TornadoABI } from "./TornadoABI"; +export type { TornadoProxyABI } from "./TornadoProxyABI"; +export * as factories from "./factories"; +export { AggregatorAbi__factory } from "./factories/AggregatorAbi__factory"; +export { ERC20Abi__factory } from "./factories/ERC20Abi__factory"; +export { MulticallAbi__factory } from "./factories/MulticallAbi__factory"; +export { OffchainOracleAbi__factory } from "./factories/OffchainOracleAbi__factory"; +export { ProxyLightABI__factory } from "./factories/ProxyLightABI__factory"; +export { TornadoABI__factory } from "./factories/TornadoABI__factory"; +export { TornadoProxyABI__factory } from "./factories/TornadoProxyABI__factory"; diff --git a/src/config.ts b/src/config.ts index b24952e..6416ba1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -6,7 +6,7 @@ require('dotenv').config(); export const netId = Number(process.env.NET_ID || 1); export const redisUrl = process.env.REDIS_URL || 'redis://127.0.0.1:6379'; export const rpcUrl = process.env.RPC_URL; -export const oracleRpcUrl = process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/'; +export const mainnetRpcUrl = process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/'; export const offchainOracleAddress = '0x07D91f5fb9Bf7798734C3f606dB065549F6893bb'; export const multiCallAddress = '0xda3c19c6fe954576707fa24695efb830d9cca1ca'; export const aggregatorAddress = process.env.AGGREGATOR; @@ -25,6 +25,7 @@ export const gasLimits = { [RelayerJobType.MINING_WITHDRAW]: 400000, }; export const minimumBalance = '1000000000000000000'; +export const minimumTornBalance = '50000000000000000000'; export const baseFeeReserve = Number(process.env.BASE_FEE_RESERVE_PERCENTAGE); export const tornToken = { tokenAddress: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C', diff --git a/src/modules/contracts.ts b/src/modules/contracts.ts index 67f6908..3350396 100644 --- a/src/modules/contracts.ts +++ b/src/modules/contracts.ts @@ -1,15 +1,16 @@ import { + ERC20Abi__factory, MulticallAbi__factory, OffchainOracleAbi__factory, ProxyLightABI__factory, TornadoProxyABI__factory, } from '../../contracts'; import { providers } from 'ethers'; -import { rpcUrl, multiCallAddress, netId, offchainOracleAddress, oracleRpcUrl } from '../config'; +import { multiCallAddress, netId, offchainOracleAddress, mainnetRpcUrl, rpcUrl } from '../config'; -export function getProvider(isStatic = true, customRpcUrl?: string) { - if (isStatic) return new providers.StaticJsonRpcProvider(customRpcUrl || rpcUrl, netId); - else return new providers.JsonRpcProvider(customRpcUrl || rpcUrl, netId); +export function getProvider(isStatic = true, customRpcUrl?: string, chainId = netId) { + if (isStatic) return new providers.StaticJsonRpcProvider(customRpcUrl || rpcUrl, chainId); + else return new providers.JsonRpcProvider(customRpcUrl || rpcUrl, chainId); } @@ -22,13 +23,16 @@ export const getTornadoProxyLightContract = (proxyAddress: string) => { export const getOffchainOracleContract = () => { - return OffchainOracleAbi__factory.connect(offchainOracleAddress, getProvider(true, oracleRpcUrl)); + return OffchainOracleAbi__factory.connect(offchainOracleAddress, getProvider(true, mainnetRpcUrl)); }; export const getMultiCallContract = () => { - return MulticallAbi__factory.connect(multiCallAddress, getProvider(true, oracleRpcUrl)); + return MulticallAbi__factory.connect(multiCallAddress, getProvider(true, mainnetRpcUrl)); }; +export const getTornTokenContract = (tokenAddress: string) => { + return ERC20Abi__factory.connect(tokenAddress, getProvider(true, mainnetRpcUrl)); +}; // export const getAggregatorContract = () => { // return AggregatorAbi__factory.connect(aggregatorAddress, getProvider()); // }; diff --git a/src/modules/ensResolver.ts b/src/modules/ensResolver.ts index c98fee4..f61db7a 100644 --- a/src/modules/ensResolver.ts +++ b/src/modules/ensResolver.ts @@ -1,10 +1,12 @@ import { getProvider } from './contracts'; +import { mainnetRpcUrl } from '../config'; +import { ChainIds } from '../types'; const addresses = new Map(); -const provider = getProvider(); async function resolve(domain: string) { try { + const provider = getProvider(true, mainnetRpcUrl, ChainIds.ethereum); if (!addresses.has(domain)) { const resolved = await provider.resolveName(domain); addresses.set(domain, resolved); diff --git a/src/services/config.service.ts b/src/services/config.service.ts index 18e4d7c..e1ca71f 100644 --- a/src/services/config.service.ts +++ b/src/services/config.service.ts @@ -1,6 +1,7 @@ import { instances, minimumBalance, + minimumTornBalance, netId, networkConfig, privateKey, @@ -10,14 +11,20 @@ import { tornToken, } from '../config'; import { Token } from '../types'; -import { getProvider, getTornadoProxyContract, getTornadoProxyLightContract } from '../modules/contracts'; +import { + getProvider, + getTornadoProxyContract, + getTornadoProxyLightContract, + getTornTokenContract, +} from '../modules/contracts'; import { resolve } from '../modules'; -import { ProxyLightABI, TornadoProxyABI } from '../../contracts'; +import { ERC20Abi, ProxyLightABI, TornadoProxyABI } from '../../contracts'; import { availableIds, netIds, NetInstances } from '../../../torn-token'; -import { getAddress } from 'ethers/lib/utils'; +import { formatEther, getAddress } from 'ethers/lib/utils'; import { providers, Wallet } from 'ethers'; import { container, singleton } from 'tsyringe'; import { GasPrice } from 'gas-price-oracle/lib/types'; +import { configService } from './index'; type relayerQueueName = `relayer_${availableIds}` @@ -39,6 +46,8 @@ export class ConfigService { isInit: boolean; nativeCurrency: string; fallbackGasPrices: GasPrice; + private _tokenAddress: string; + private _tokenContract: ERC20Abi; constructor() { @@ -85,8 +94,10 @@ export class ConfigService { try { if (this.isInit) return; await this._checkNetwork(); + this._tokenAddress = await resolve(torn.torn.address); + this._tokenContract = await getTornTokenContract(this._tokenAddress); if (this.isLightMode) { - this._proxyAddress = await resolve(torn.tornadoProxyLight.address); + this._proxyAddress = torn.tornadoProxyLight.address; this._proxyContract = getTornadoProxyLightContract(this._proxyAddress); const { gasPrices, nativeCurrency } = networkConfig[this.netIdKey]; this.nativeCurrency = nativeCurrency; @@ -106,10 +117,19 @@ export class ConfigService { decimals: el.decimals, symbol: el.symbol, })).filter(Boolean); + const { balance } = await configService.getBalance(); + const { balance: tornBalance } = await configService.getTornBalance(); console.log( - `Configuration completed\n-- netId: ${this.netId}\n-- rpcUrl: ${this.rpcUrl}`); + 'Configuration completed\n', + `-- netId: ${this.netId}\n`, + `-- rpcUrl: ${this.rpcUrl}\n`, + `-- relayer Address: ${this.wallet.address}\n`, + `-- relayer Balance: ${formatEther(balance)}\n`, + `-- relayer Torn balance: ${formatEther(tornBalance)}\n`, + ); + + this.isInit = true; - console.log(this); } catch (e) { console.error(`${this.constructor.name} Error:`, e.message); } @@ -125,6 +145,12 @@ export class ConfigService { return { balance, isEnougth }; } + async getTornBalance() { + const balance = await this._tokenContract.balanceOf(this.wallet.address); + const isEnougth = balance.gt(minimumTornBalance); + return { balance, isEnougth }; + } + } type InstanceProps = { diff --git a/src/types.ts b/src/types.ts index 4c324ad..abb4c89 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,4 +14,66 @@ export enum JobStatus { FAILED = 'FAILED', } + export type Token = { address: string, decimals: number, symbol?: string } + +export enum ChainIds { + 'kardia' = 0, + 'ethereum' = 1, + 'ubiq' = 8, + 'optimism' = 10, + 'songbird' = 19, + 'elastos' = 20, + 'cronos' = 25, + 'rsk' = 30, + 'telos' = 40, + 'csc' = 52, + 'zyx' = 55, + 'binance' = 56, + 'syscoin' = 57, + 'gochain' = 60, + 'ethclassic' = 61, + 'okexchain' = 66, + 'hoo' = 70, + 'meter' = 82, + 'tomochain' = 88, + 'xdai' = 100, + 'velas' = 106, + 'thundercore' = 108, + 'fuse' = 122, + 'heco' = 128, + 'polygon' = 137, + 'xdaiarb' = 200, + 'energyweb' = 246, + 'fantom' = 250, + 'hpb' = 269, + 'boba' = 288, + 'kucoin' = 321, + 'shiden' = 336, + 'theta' = 361, + 'candle' = 534, + 'astar' = 592, + 'callisto' = 820, + 'wanchain' = 888, + 'metis' = 1088, + 'moonbeam' = 1284, + 'moonriver' = 1285, + 'ronin' = 2020, + 'ezchain' = 2612, + 'iotex' = 4689, + 'xlc' = 5050, + 'nahmii' = 5551, + 'klaytn' = 8217, + 'smartbch' = 10000, + 'fusion' = 32659, + 'arbitrum' = 42161, + 'celo' = 42220, + 'oasis' = 42262, + 'avalanche' = 43114, + 'godwoken' = 71394, + 'polis' = 333999, + 'aurora' = 1313161554, + 'harmony' = 1666600000, + 'palm' = 11297108109, + 'curio' = 836542336838601, +}