tornado-relayer/src/utils.js

179 lines
4.4 KiB
JavaScript
Raw Normal View History

2019-12-18 22:25:09 +03:00
const { isHexStrict, toBN, toWei, BN } = require('web3-utils')
2019-12-02 15:49:24 +03:00
const { netId, mixers, relayerServiceFee } = require('../config')
2019-09-19 18:21:57 +03:00
2019-11-14 16:24:01 +03:00
function isValidProof(proof) {
2019-07-18 15:43:26 +03:00
// validator expects `websnarkUtils.toSolidityInput(proof)` output
2020-08-04 10:39:56 +03:00
if (!proof) {
2019-11-14 16:24:01 +03:00
return { valid: false, reason: 'The proof is empty.' }
2019-07-18 15:43:26 +03:00
}
2019-11-14 16:24:01 +03:00
if (!isHexStrict(proof) || proof.length !== 2 + 2 * 8 * 32) {
2019-10-06 10:55:24 +03:00
return { valid: false, reason: 'Corrupted proof' }
2019-07-18 15:43:26 +03:00
}
2019-11-14 16:24:01 +03:00
return { valid: true }
}
function isValidArgs(args) {
2020-08-04 10:39:56 +03:00
if (!args) {
2019-11-14 16:24:01 +03:00
return { valid: false, reason: 'Args are empty' }
}
if (args.length !== 6) {
return { valid: false, reason: 'Length of args is lower than 6' }
2019-07-18 15:43:26 +03:00
}
2020-08-04 10:39:56 +03:00
for (let signal of args) {
2019-11-08 04:25:43 +03:00
if (!isHexStrict(signal)) {
2019-11-14 16:24:01 +03:00
return { valid: false, reason: `Corrupted signal ${signal}` }
2019-07-18 15:43:26 +03:00
}
}
2019-11-08 04:25:43 +03:00
2020-08-04 10:39:56 +03:00
if (
args[0].length !== 66 ||
args[1].length !== 66 ||
args[2].length !== 42 ||
args[3].length !== 42 ||
args[4].length !== 66 ||
args[5].length !== 66
) {
2019-11-14 16:24:01 +03:00
return { valid: false, reason: 'The length one of the signals is incorrect' }
2019-11-08 04:25:43 +03:00
}
2019-07-18 15:43:26 +03:00
return { valid: true }
}
2019-09-19 22:56:45 +03:00
function isKnownContract(contract) {
2019-12-02 15:49:24 +03:00
const mixers = getMixers()
for (let currency of Object.keys(mixers)) {
for (let amount of Object.keys(mixers[currency].mixerAddress)) {
if (mixers[currency].mixerAddress[amount] === contract) {
return { valid: true, currency, amount }
}
2019-09-19 22:56:45 +03:00
}
}
return { valid: false }
}
2019-07-23 19:43:24 +03:00
function sleep(ms) {
2020-08-04 10:39:56 +03:00
return new Promise((resolve) => setTimeout(resolve, ms))
2019-07-23 19:43:24 +03:00
}
2019-12-18 22:25:09 +03:00
function fromDecimals(value, decimals) {
value = value.toString()
let ether = value.toString()
const base = new BN('10').pow(new BN(decimals))
const baseLength = base.toString(10).length - 1 || 1
const negative = ether.substring(0, 1) === '-'
if (negative) {
ether = ether.substring(1)
}
if (ether === '.') {
throw new Error('[ethjs-unit] while converting number ' + value + ' to wei, invalid value')
}
// Split it into a whole and fractional part
const comps = ether.split('.')
if (comps.length > 2) {
2020-08-04 10:39:56 +03:00
throw new Error('[ethjs-unit] while converting number ' + value + ' to wei, too many decimal points')
2019-12-18 22:25:09 +03:00
}
let whole = comps[0]
let fraction = comps[1]
if (!whole) {
whole = '0'
}
if (!fraction) {
fraction = '0'
}
if (fraction.length > baseLength) {
2020-08-04 10:39:56 +03:00
throw new Error('[ethjs-unit] while converting number ' + value + ' to wei, too many decimal places')
2019-12-18 22:25:09 +03:00
}
while (fraction.length < baseLength) {
fraction += '0'
}
whole = new BN(whole)
fraction = new BN(fraction)
let wei = whole.mul(base).add(fraction)
if (negative) {
wei = wei.mul(negative)
}
return new BN(wei.toString(10), 10)
}
2019-11-26 18:01:37 +03:00
function isEnoughFee({ gas, gasPrices, currency, amount, refund, ethPrices, fee }) {
2019-12-18 22:25:09 +03:00
const { decimals } = mixers[`netId${netId}`][currency]
2020-08-04 10:39:56 +03:00
const decimalsPoint =
Math.floor(relayerServiceFee) === relayerServiceFee
? 0
: relayerServiceFee.toString().split('.')[1].length
const roundDecimal = 10 ** decimalsPoint
2020-08-04 10:39:56 +03:00
const feePercent = toBN(fromDecimals(amount, decimals))
.mul(toBN(relayerServiceFee * roundDecimal))
.div(toBN(roundDecimal * 100))
2019-11-15 12:01:59 +03:00
const expense = toBN(toWei(gasPrices.fast.toString(), 'gwei')).mul(toBN(gas))
let desiredFee
switch (currency) {
case 'eth': {
2019-11-26 18:01:37 +03:00
desiredFee = expense.add(feePercent)
2019-11-15 12:01:59 +03:00
break
}
2019-12-18 22:25:09 +03:00
default: {
2020-08-04 10:39:56 +03:00
desiredFee = expense
.add(refund)
.mul(toBN(10 ** decimals))
.div(toBN(ethPrices[currency]))
2019-11-26 18:01:37 +03:00
desiredFee = desiredFee.add(feePercent)
2019-11-15 12:01:59 +03:00
break
}
}
2020-08-04 10:39:56 +03:00
console.log(
'sent fee, desired fee, feePercent',
fee.toString(),
desiredFee.toString(),
feePercent.toString()
)
2019-11-15 12:01:59 +03:00
if (fee.lt(desiredFee)) {
return { isEnough: false, reason: 'Not enough fee' }
2020-08-04 10:39:56 +03:00
}
2019-11-15 12:01:59 +03:00
return { isEnough: true }
}
2019-12-23 19:38:44 +03:00
function getArgsForOracle() {
2019-12-02 15:49:24 +03:00
const tokens = mixers['netId1']
const tokenAddresses = []
2019-12-23 19:38:44 +03:00
const oneUintAmount = []
2019-12-02 15:49:24 +03:00
const currencyLookup = {}
Object.entries(tokens).map(([currency, data]) => {
if (currency !== 'eth') {
tokenAddresses.push(data.tokenAddress)
2020-08-04 10:39:56 +03:00
oneUintAmount.push(toBN('10').pow(toBN(data.decimals.toString())).toString())
2019-12-23 19:38:44 +03:00
currencyLookup[data.tokenAddress] = currency
2019-12-02 15:49:24 +03:00
}
})
2019-12-23 22:40:08 +03:00
return { tokenAddresses, oneUintAmount, currencyLookup }
2019-12-02 15:49:24 +03:00
}
function getMixers() {
return mixers[`netId${netId}`]
}
2020-08-04 10:39:56 +03:00
module.exports = {
isValidProof,
isValidArgs,
sleep,
isKnownContract,
isEnoughFee,
getMixers,
getArgsForOracle
}