Price logic for tokens usin cryptocompare

This commit is contained in:
Richard Ramos 2018-09-17 14:19:56 -04:00
parent 4dd59e4ff9
commit 3c1f70df9a
6 changed files with 81 additions and 19 deletions

View File

@ -1,15 +1,40 @@
const axios = require('axios');
class TokenUtils { class TokenUtils {
constructor(tokenConfig){ constructor(tokenConfig, gasPrice){
this.gasPrice = gasPrice;
this.name = tokenConfig.name || ""; this.name = tokenConfig.name || "";
this.symbol = tokenConfig.symbol || ""; this.symbol = tokenConfig.symbol || "";
this.minRelayFactor = tokenConfig.minRelayFactor || 1; this.minRelayFactor = tokenConfig.minRelayFactor || 1;
} }
getFactor(){ async getRate(){
// TODO get price from somewhere // Using cryptocompare API
return 100000; const doc = await axios.get('https://min-api.cryptocompare.com/data/price?fsym=' + this.symbol + '&tsyms=ETH');
return parseFloat(doc.data.ETH);
}
calculateMinGasPrice(estimatedGas, currentPrice){
// Example
// Cost for a simple ETH transaction: 21000
// Rate between SNT & ETH = 0.0001562;
//
// Total SNT that should be spent for a transaction at the previous price:
// 21000 / 0.0001562 = 134443021
//
// Min Gas Price = Total SNT / Cost for Transaction
// 134443021 / 21000 = 6402
const totalGasCost = parseInt(estimatedGas, 10) * this.gasPrice;
const totalTokenCost = totalGasCost / currentPrice;
const minGasPrice = Math.ceil(totalTokenCost / totalGasCost);
return minGasPrice;
} }
} }
module.exports = TokenUtils; module.exports = TokenUtils;

View File

@ -35,7 +35,7 @@ class ContractSettings {
for(let token in this.tokens){ for(let token in this.tokens){
if(this.tokens[token].pricePlugin !== undefined){ if(this.tokens[token].pricePlugin !== undefined){
let PricePlugin = require(this.tokens[token].pricePlugin); let PricePlugin = require(this.tokens[token].pricePlugin);
this.tokens[token].pricePlugin = new PricePlugin(this.tokens[token]); this.tokens[token].pricePlugin = new PricePlugin(this.tokens[token], this.config.gasPrice);
} }
} }
} }

View File

@ -168,7 +168,10 @@ events.on('server:listen', (shhOptions, settings) => {
reply, reply,
settings.buildStrategy("./strategy/AvailabilityStrategy", message.topic) settings.buildStrategy("./strategy/AvailabilityStrategy", message.topic)
); );
if(validationResult.success) reply(validationResult.message); if(validationResult.success && validationResult.message) {
messagesCheckSum[inputCheckSum] = (new Date().getTime());
reply(validationResult.message);
}
break; break;
default: default:
@ -188,6 +191,7 @@ const deleteOldChecksums = () => {
} }
} }
}; };
setInterval(deleteOldChecksums, 3600000); setInterval(deleteOldChecksums, 3600000);
// Daemon helper functions // Daemon helper functions

View File

@ -11,23 +11,29 @@ class AvailabilityStrategy extends Strategy {
* @param {object} input - Object obtained from an 'availability' request. It expects an object with this structure `{contract, address, action, gasToken, gasPrice}` * @param {object} input - Object obtained from an 'availability' request. It expects an object with this structure `{contract, address, action, gasToken, gasPrice}`
* @returns {object} Status of validation, and minimum price * @returns {object} Status of validation, and minimum price
*/ */
execute(input){ async execute(input){
// Verifying if token is allowed // Verifying if token is allowed
const token = this.settings.getToken(input.gasToken); const token = this.settings.getToken(input.gasToken);
if(token == undefined) return {success: false, message: "Token not allowed"}; if(token == undefined) return {success: false, message: "Token not allowed"};
// TODO: Validate gasPrice, and return the minPrice accepted
const minPrice = 0.00;
// Get Price
const tokenRate = await token.pricePlugin.getRate();
const minRate = token.minAcceptedRate;
if(tokenRate >= minRate){ // TODO: verify this
return { return {
success: true, success: true,
message: { message: {
message: "Available", message: "Available",
address: this.config.node.blockchain.account, address: this.config.node.blockchain.account,
minAcceptedGasPrice: minPrice, acceptedRate: tokenRate,
gasPriceUsed: this.config.gasPrice gasPriceUsed: this.config.gasPrice
} }
}; };
} else {
return {success: true};
}
} }
} }

View File

@ -86,6 +86,19 @@ class IdentityStrategy extends Strategy {
} }
} }
// Get Price
const tokenRate = await token.pricePlugin.getRate();
const minRate = token.minAcceptedRate;
if(tokenRate < minRate){ // TODO: verify this. Maybe we want to accept a minRate instead of just simply not processing the trx
return {success: false, message: "Not accepting " + token.symbol + " at current rate. (Min rate: " + token.minAcceptedRate+ ")"};
}
const minGasPrice = this.web3.utils.toBN(token.pricePlugin.calculateMinGasPrice(estimatedGas.toString(10), tokenRate));
if(gasPrice.lt(minGasPrice)){
return {success: false, message: "Gas price is less than the required amount (" + minGasPrice.toString(10) + ")"};
}
return { return {
success: true, success: true,
message: "Valid transaction", message: "Valid transaction",

View File

@ -29,6 +29,20 @@ class SNTStrategy extends Strategy {
to: input.contract to: input.contract
}); });
// Get Price
const tokenRate = await token.pricePlugin.getRate();
const minRate = token.minAcceptedRate;
if(tokenRate < minRate){ // TODO: verify this. Maybe we want to accept a minRate instead of just simply not processing the trx
return {success: false, message: "Not accepting " + token.symbol + " at current rate. (Min rate: " + token.minAcceptedRate+ ")"};
}
const gasPrice = this.web3.utils.toBN(params('_gasPrice'));
const minGasPrice = this.web3.utils.toBN(token.pricePlugin.calculateMinGasPrice(estimatedGas.toString(10), tokenRate));
if(gasPrice.lt(minGasPrice)){
return {success: false, message: "Gas price is less than the required amount (" + minGasPrice.toString(10) + ")"};
}
if(input.functionName == TransferSNT){ if(input.functionName == TransferSNT){
const gas = this.web3.utils.toBN(estimatedGas); const gas = this.web3.utils.toBN(estimatedGas);
const value = this.web3.utils.toBN(params('_amount')); const value = this.web3.utils.toBN(params('_amount'));