service fee handling
This commit is contained in:
parent
ab088a0855
commit
1edc8ff69c
@ -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
|
11
config.js
11
config.js
@ -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)
|
||||||
@ -43,4 +43,5 @@ console.log(`relayerAddress: ${web3.eth.defaultAccount}`)
|
|||||||
console.log(`mixers: ${JSON.stringify(mixers)}`)
|
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 })
|
||||||
|
13
src/utils.js
13
src/utils.js
@ -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' }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user