autobounty/bot/index.js

184 lines
5.6 KiB
JavaScript

const winston = require('winston')
const ethers = require('ethers')
const Wallet = ethers.Wallet
const Contract = ethers.Contract
const providers = ethers.providers
const utils = ethers.utils
const prices = require('./prices')
const config = require('../config')
const github = require('./github')
const contractAddressString = 'Contract address:'
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: './log/error.log', level: 'error' }),
new winston.transports.File({ filename: './log/info.log', level: 'info' }),
// new winston.transports.File({ filename: './log/combined.log' })
]
})
const needsFunding = function (req) {
if (req.body.action !== 'edited' || !req.body.hasOwnProperty('comment')) {
return false
} else if (req.body.comment.user.login !== config.githubUsername) {
return false
} else if (!hasAddress(req)) {
return false
}
return true
}
const hasAddress = function (req) {
const commentBody = req.body.comment.body
if (commentBody.search(contractAddressString) === -1) {
return false
} else {
return true
}
}
const getAddress = function (req) {
const commentBody = req.body.comment.body
const index = commentBody.search(contractAddressString) + 19
return commentBody.substring(index, index + 42)
}
const getLabel = function (req) {
return new Promise((resolve, reject) => {
github.getLabels(req)
.then(labels => {
const bountyLabels = labels.filter(label => config.bountyLabels.hasOwnProperty(label.name))
if (bountyLabels.length === 1) {
resolve(bountyLabels[0])
} else {
reject('Error getting bounty labels')
}
}).catch(err => {
reject(err)
})
})
}
const getAmountMock = function (req) {
return new Promise((resolve, reject) => {
resolve(10)
})
}
const getAmount = function (req) {
return new Promise((resolve, reject) => {
const labelPromise = getLabel(req)
const tokenPricePromise = prices.getTokenPrice(config.token)
Promise.all([labelPromise, tokenPricePromise])
.then(function (values) {
const label = values[0]
const tokenPrice = values[1]
const amountToPayDollar = config.priceHour * config.bountyLabels[label.name]
resolve(amountToPayDollar / tokenPrice)
})
.catch((err) => {
reject(err)
})
})
}
// Logging functions
const logTransaction = function (tx) {
logger.info("[OK] Succesfully funded bounty with transaction " + tx.hash)
logger.info(" * From: " + tx.from)
logger.info(" * To: " + tx.to)
logger.info(" * Amount: " + tx.value)
logger.info(" * Gas Price: " + tx.gasPrice)
logger.info("====================================================")
}
const info = function (msg) {
logger.info(msg)
}
const error = function (errorMessage) {
logger.error("[ERROR] Request processing failed: " + errorMessage)
}
const sendTransaction = async function (to, amount, gasPrice) {
let chainId = providers.Provider.chainId.ropsten
let chainName = providers.networks.ropsten
if (config.realTransaction) {
chainId = providers.Provider.chainId.homestead
chainName = providers.networks.homestead
}
const wallet = new Wallet(config.privateKey)
const provider = ethers.providers.getDefaultProvider(chainName)
wallet.provider = provider
if (config.token === 'ETH') {
const transaction = {
gasLimit: config.gasLimit,
gasPrice: gasPrice,
to: to,
value: amount,
chainId: chainId
}
return await wallet.sendTransaction(transaction)
} else {
let hash = null
async function getAddress() { return wallet.address }
async function sign(transaction) { return wallet.sign(transaction) }
async function resolveName(addressOrName) { return await provider.resolveName(addressOrName) }
async function estimateGas(transaction) { return await provider.estimateGas(transaction) }
async function getGasPrice() { return await provider.getGasPrice() }
async function getTransactionCount(blockTag) { return await provider.getTransactionCount(blockTag) }
async function sendTransaction(transaction) {
hash = await provider.sendTransaction(transaction)
return hash
}
const customSigner = {
getAddress: getAddress,
provider: {
resolveName: resolveName,
estimateGas: estimateGas,
getGasPrice: getGasPrice,
getTransactionCount: getTransactionCount,
sendTransaction: sendTransaction
},
sign: sign
}
const tokenContract = config.tokenContracts[config.token]
const contractAddress = tokenContract.address
const contract = new Contract(contractAddress, tokenContract.abi, customSigner)
const bigNumberAmount = ethers.utils.bigNumberify(amount)
await contract.transfer(to, bigNumberAmount)
return hash
}
}
module.exports = {
needsFunding: needsFunding,
getAddress: getAddress,
getAmount: getAmount,
getGasPrice: prices.getGasPrice,
sendTransaction: sendTransaction,
info: info,
logTransaction: logTransaction,
error: error
}