service fee handling

This commit is contained in:
Alexey 2019-11-26 18:01:37 +03:00
parent ab088a0855
commit 1edc8ff69c
5 changed files with 24 additions and 15 deletions

@ -3,5 +3,7 @@ RPC_URL=https://kovan.infura.io/v3/a3f4d001c1fc4a359ea70dd27fd9cb51
PRIVATE_KEY= PRIVATE_KEY=
ETH_MIXER_ADDRESS=0x1Cea940cA15a303A0E01B7F8589F39fF34308DB2 ETH_MIXER_ADDRESS=0x1Cea940cA15a303A0E01B7F8589F39fF34308DB2
DAI_MIXER_ADDRESS=0x7ed3fC8042e18db889A0466F49c438bB1410b3c7 DAI_MIXER_ADDRESS=0x7ed3fC8042e18db889A0466F49c438bB1410b3c7
# 25 means 2.5%
RELAYER_FEE=25
APP_PORT=8000 APP_PORT=8000

@ -1,20 +1,23 @@
require('dotenv').config() require('dotenv').config()
module.exports = { module.exports = {
netId: process.env.NET_ID || 42, netId: Number(process.env.NET_ID) || 42,
rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/v3/a3f4d001c1fc4a359ea70dd27fd9cb51', rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/v3/a3f4d001c1fc4a359ea70dd27fd9cb51',
privateKey: process.env.PRIVATE_KEY, privateKey: process.env.PRIVATE_KEY,
mixers: [ { mixers: [ {
address: process.env.ETH_MIXER_ADDRESS, address: process.env.ETH_MIXER_ADDRESS,
currency: 'eth' currency: 'eth',
amount: '0.1'
}, },
{ {
address: process.env.DAI_MIXER_ADDRESS, address: process.env.DAI_MIXER_ADDRESS,
currency: 'dai' currency: 'dai',
amount: '100'
} ], } ],
defaultGasPrice: 2, defaultGasPrice: 2,
gasOracleUrls: ['https://www.etherchain.org/api/gasPriceOracle', 'https://gasprice.poa.network/'], gasOracleUrls: ['https://www.etherchain.org/api/gasPriceOracle', 'https://gasprice.poa.network/'],
port: process.env.APP_PORT, port: process.env.APP_PORT,
//dai //dai
tokens: ['0x6b175474e89094c44da98b954eedeac495271d0f'] tokens: ['0x6b175474e89094c44da98b954eedeac495271d0f'],
relayerServiceFee: process.env.RELAYER_FEE
} }

@ -1,5 +1,5 @@
const express = require('express') const express = require('express')
const { netId, mixers, port } = require('../config') const { netId, mixers, port, relayerServiceFee } = require('../config')
const relayController = require('./relayController') const relayController = require('./relayController')
const { fetcher, web3 } = require('./instances') const { fetcher, web3 } = require('./instances')
@ -28,7 +28,7 @@ app.get('/', function (req, res) {
app.get('/status', function (req, res) { app.get('/status', function (req, res) {
const { ethPrices, gasPrices } = fetcher const { ethPrices, gasPrices } = fetcher
res.json({ relayerAddress: web3.eth.defaultAccount, mixers, gasPrices, netId, ethPrices }) res.json({ relayerAddress: web3.eth.defaultAccount, mixers, gasPrices, netId, ethPrices, relayerServiceFee })
}) })
app.post('/relay', relayController) app.post('/relay', relayController)
@ -44,3 +44,4 @@ console.log(`mixers: ${JSON.stringify(mixers)}`)
console.log(`gasPrices: ${JSON.stringify(fetcher.gasPrices)}`) console.log(`gasPrices: ${JSON.stringify(fetcher.gasPrices)}`)
console.log(`netId: ${netId}`) console.log(`netId: ${netId}`)
console.log(`ethPrices: ${JSON.stringify(fetcher.ethPrices)}`) console.log(`ethPrices: ${JSON.stringify(fetcher.ethPrices)}`)
console.log(`Service fee: ${relayerServiceFee / 10}%`)

@ -21,8 +21,8 @@ async function relay (req, resp) {
return resp.status(400).json({ error: 'Withdraw arguments are invalid' }) return resp.status(400).json({ error: 'Withdraw arguments are invalid' })
} }
let currency let currency, amount
( { valid, currency } = isKnownContract(contract)) ( { valid, currency, amount } = isKnownContract(contract))
if (!valid) { if (!valid) {
console.log('Contract does not exist:', contract) console.log('Contract does not exist:', contract)
return resp.status(400).json({ error: 'This relayer does not support the token' }) return resp.status(400).json({ error: 'This relayer does not support the token' })
@ -73,7 +73,7 @@ async function relay (req, resp) {
gas += 50000 gas += 50000
const ethPrices = fetcher.ethPrices const ethPrices = fetcher.ethPrices
const { isEnough, reason } = isEnoughFee({ gas, gasPrices, currency, refund, ethPrices, fee }) const { isEnough, reason } = isEnoughFee({ gas, gasPrices, currency, amount, refund, ethPrices, fee })
if (!isEnough) { if (!isEnough) {
console.log(`Wrong fee: ${reason}`) console.log(`Wrong fee: ${reason}`)
return resp.status(400).json({ error: reason }) return resp.status(400).json({ error: reason })

@ -1,5 +1,5 @@
const { isHexStrict, toBN, toWei } = require('web3-utils') const { isHexStrict, toBN, toWei } = require('web3-utils')
const { mixers } = require('../config') const { mixers, relayerServiceFee } = require('../config')
function isValidProof(proof) { function isValidProof(proof) {
// validator expects `websnarkUtils.toSolidityInput(proof)` output // validator expects `websnarkUtils.toSolidityInput(proof)` output
@ -46,7 +46,7 @@ function isValidArgs(args) {
function isKnownContract(contract) { function isKnownContract(contract) {
for (let i = 0; i < mixers.length; i++) { for (let i = 0; i < mixers.length; i++) {
if (mixers[i].address === contract) { if (mixers[i].address === contract) {
return { valid: true, currency: mixers[i].currency } return { valid: true, currency: mixers[i].currency, amount: mixers[i].amount }
} }
} }
return { valid: false } return { valid: false }
@ -56,12 +56,14 @@ function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms)) return new Promise(resolve => setTimeout(resolve, ms))
} }
function isEnoughFee({ gas, gasPrices, currency, refund, ethPrices, fee }) { 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)).div(toBN('1000'))
const expense = toBN(toWei(gasPrices.fast.toString(), 'gwei')).mul(toBN(gas)) const expense = toBN(toWei(gasPrices.fast.toString(), 'gwei')).mul(toBN(gas))
let desiredFee let desiredFee
switch (currency) { switch (currency) {
case 'eth': { case 'eth': {
desiredFee = expense desiredFee = expense.add(feePercent)
break break
} }
case 'dai': { case 'dai': {
@ -69,10 +71,11 @@ function isEnoughFee({ gas, gasPrices, currency, refund, ethPrices, fee }) {
expense.add(refund) expense.add(refund)
.mul(toBN(10 ** 18)) .mul(toBN(10 ** 18))
.div(toBN(ethPrices.dai)) .div(toBN(ethPrices.dai))
desiredFee = desiredFee.add(feePercent)
break break
} }
} }
console.log('desired fee', desiredFee.toString()) console.log('desired fee, feePercent', desiredFee.toString(), feePercent.toString())
if (fee.lt(desiredFee)) { if (fee.lt(desiredFee)) {
return { isEnough: false, reason: 'Not enough fee' } return { isEnough: false, reason: 'Not enough fee' }
} }