630 lines
32 KiB
JavaScript
630 lines
32 KiB
JavaScript
const config = require('./config');
|
|
const { getPathObj, getPathNum } = require("./getPathObj");
|
|
const { store } = require("./index");
|
|
const { isEmpty, addMT } = require('./lil_ops')
|
|
const { sortBuyArray } = require('./helpers');
|
|
const stringify = require('json-stable-stringify');
|
|
|
|
//the daily post, the inflation point for tokennomics
|
|
function dao(num) {
|
|
return new Promise((resolve, reject) => {
|
|
let post = `## SPK Claim Chain REPORT\n`,
|
|
news = '',
|
|
daops = [],
|
|
Pnews = new Promise(function(resolve, reject) {
|
|
store.get(['postQueue'], function(err, obj) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
var news = isEmpty(obj) ? '' : '*****\n### News from Humans!\n';
|
|
for (var title in obj) { //postQueue[title].{title,text}
|
|
news = news + `#### ${title}\n`;
|
|
news = news + `${obj[title].text}\n\n`;
|
|
}
|
|
resolve(news);
|
|
}
|
|
});
|
|
}),
|
|
Pbals = getPathObj(['balances']),
|
|
Pcbals = getPathObj(['cbalances'])
|
|
Prunners = getPathObj(['runners']),
|
|
Pnodes = getPathObj(['markets', 'node']),
|
|
Pstats = getPathObj(['stats']),
|
|
Pdelegations = getPathObj(['delegations']),
|
|
Pico = getPathObj(['ico']),
|
|
Pdex = getPathObj(['dex']),
|
|
Pbr = getPathObj(['br']),
|
|
Ppbal = getPathNum(['gov', 't']),
|
|
Pgov = getPathObj(['gov']),
|
|
Pnomen = getPathObj(['nomention']),
|
|
Pposts = getPathObj(['posts']),
|
|
Pfeed = getPathObj(['feed']),
|
|
Ppaid = getPathObj(['paid']),
|
|
Prnfts = getPathObj(['rnfts']);
|
|
Pdistro = Distro()
|
|
Promise.all([Pnews, Pbals, Prunners, Pnodes, Pstats, Pdelegations, Pico, Pdex, Pbr, Ppbal, Pnomen, Pposts, Pfeed, Ppaid, Prnfts, Pdistro, Pcbals, Pgov]).then(function(v) {
|
|
daops.push({ type: 'del', path: ['postQueue'] });
|
|
daops.push({ type: 'del', path: ['br'] });
|
|
daops.push({ type: 'del', path: ['rolling'] });
|
|
daops.push({ type: 'del', path: ['ico'] });
|
|
// daops.push({ type: 'del', path: ['markets', 'node'] })
|
|
news = v[0] + '*****\n';
|
|
const header = post + news;
|
|
var bals = v[1],
|
|
cbals = v[16],
|
|
runners = v[2],
|
|
mnode = v[3],
|
|
stats = v[4],
|
|
deles = v[5],
|
|
ico = v[6],
|
|
dex = v[7],
|
|
br = v[8],
|
|
powBal = v[9],
|
|
nomention = v[10],
|
|
cpost = v[11],
|
|
feedCleaner = v[12],
|
|
paidCleaner = v[13],
|
|
rnftsCleaner = v[14];
|
|
dist = v[15],
|
|
gov = v[17]
|
|
for(var i = 0; i < dist.length;i++){
|
|
if(dist[i][0].split('div:')[1]){
|
|
addMT(['div', dist[i][0].split('div:')[1], 'b'], dist[i][1] )
|
|
} else {
|
|
cbals[dist[i][0]] ? cbals[dist[i][0]] += dist[i][1] : cbals[dist[i][0]] = dist[i][1]
|
|
}
|
|
}
|
|
feedKeys = Object.keys(feedCleaner);
|
|
paidKeys = Object.keys(paidCleaner);
|
|
for(var set in rnftsCleaner){
|
|
rnftKeys = Object.keys(rnftsCleaner[set]);
|
|
for (var rnfti = 0; rnfti < rnftKeys.length; rnfti++) {
|
|
if (rnftsCleaner[set][rnftKeys[rnfti]] == 0) {
|
|
daops.push({ type: 'del', path: ['rnfts', set, rnftKeys[rnfti]] });
|
|
}
|
|
}
|
|
}
|
|
for (feedi = 0; feedi < feedKeys.length; feedi++) {
|
|
if (feedKeys[feedi].split(':')[0] < num - 30240) {
|
|
daops.push({ type: 'del', path: ['feed', feedKeys[feedi]] });
|
|
}
|
|
}
|
|
for (paidi = 0; paidi < paidKeys.length; paidi++) {
|
|
console.log(paidKeys[paidi])
|
|
if (parseInt(paidKeys[paidi]) < num - 30240) {
|
|
console.log(paidKeys[paidi])
|
|
daops.push({ type: 'del', path: ['paid', paidKeys[paidi].toString()] });
|
|
}
|
|
}
|
|
news = news;
|
|
var i = 0,
|
|
j = 0,
|
|
b = 0,
|
|
t = 0;
|
|
t = parseInt(bals.ra);
|
|
for (var node in runners) { //node rate
|
|
b = parseInt(b) + parseInt(mnode[node].marketingRate) || 2500;
|
|
j = parseInt(j) + parseInt(mnode[node].bidRate) || 2500;
|
|
i++;
|
|
console.log(b, j, i);
|
|
}
|
|
if (!i) {
|
|
b = mnode[config.leader].marketingRate;
|
|
j = mnode[config.leader].bidRate;
|
|
i++;
|
|
}
|
|
stats.marketingRate = parseInt(b / i);
|
|
stats.nodeRate = parseInt(j / i);
|
|
post = `![${config.TOKEN} Advert](https://files.peakd.com/file/peakd-hive/spknetwork/23t7kxv6nPpoJwgyaDY3Xrekipa9vSyCNj6qm9oQuPDby7sk81ukLAAE8VJ55Kbp116bW.png)\n#### Daily Accounting\n`;
|
|
post = post + `Total Supply: ${parseFloat(parseInt(stats.tokenSupply) / 1000).toFixed(3)} ${config.TOKEN}\n* ${parseFloat(parseInt(stats.tokenSupply - powBal - (bals.ra + bals.rc + bals.rd + bals.ri + bals.rn + bals.rm)) / 1000).toFixed(3)} ${config.TOKEN} liquid\n`;
|
|
post = post + `* ${parseFloat(parseInt(powBal) / 1000).toFixed(3)} ${config.TOKEN} Locked to Govern\n`;
|
|
post = post + `* ${parseFloat(parseInt(bals.ra + bals.rc + bals.rd + bals.ri + bals.rn + bals.rm) / 1000).toFixed(3)} ${config.TOKEN} in distribution accounts\n`;
|
|
if(config.features.inflation)post = post + `${parseFloat(parseInt(t) / 1000).toFixed(3)} ${config.TOKEN} has been generated today. 5% APY.\n${parseFloat(stats.marketingRate / 10000).toFixed(4)} is the marketing rate.\n${parseFloat(stats.nodeRate / 10000).toFixed(4)} is the node rate.\n`;
|
|
console.log(`DAO Accounting In Progress:\n${t} has been generated today\n${stats.marketingRate} is the marketing rate.\n${stats.nodeRate} is the node rate.`);
|
|
bals.rn += parseInt(t * parseInt(stats.nodeRate) / 10000);
|
|
bals.ra = parseInt(bals.ra) - parseInt(t * parseInt(stats.nodeRate) / 10000);
|
|
bals.rm += parseInt(t * stats.marketingRate / 10000);
|
|
if(stats.marketingRate)post = post + `${parseFloat(parseInt(t * stats.marketingRate / 10000) / 1000).toFixed(3)} ${config.TOKEN} moved to Marketing Allocation.\n`;
|
|
if (bals.rm > 1000000000) {
|
|
bals.rc += bals.rm - 1000000000;
|
|
post = post + `${parseFloat((bals.rm - 1000000000) / 1000).toFixed(3)} moved from Marketing Allocation to Content Allocation due to Marketing Holdings Cap of 1,000,000.000 ${config.TOKEN}\n`;
|
|
bals.rm = 1000000000;
|
|
}
|
|
bals.ra = parseInt(bals.ra) - parseInt(t * stats.marketingRate / 10000);
|
|
|
|
i = 0, j = 0;
|
|
if(bals.rm && config.features.inflation)post = post + `${parseFloat(parseInt(bals.rm) / 1000).toFixed(3)} ${config.TOKEN} is in the Marketing Allocation.\n`
|
|
if(bals.rn)post = post + `##### Node Rewards for Elected Reports and Escrow Transfers\n`;
|
|
console.log(num + `:${bals.rm} is availible in the marketing account\n${bals.rn} ${config.TOKEN} set aside to distribute to nodes`);
|
|
for (var node in mnode) { //tally the wins
|
|
j = j + parseInt(mnode[node].wins);
|
|
}
|
|
b = bals.rn;
|
|
|
|
function _atfun(node) {
|
|
if (nomention[node]) {
|
|
return '@_';
|
|
} else {
|
|
return '@';
|
|
}
|
|
}
|
|
var newOwners = {}, dexfeea = 0, dexfeed = 1, dexmaxa = 0, dexslopea = 0, dexmaxd = 1, dexsloped = 1, dva = 0, dvd = 1
|
|
if(j){
|
|
for (var node in mnode) { //and pay them
|
|
const wins = mnode[node].wins
|
|
newOwners[node] = {wins}
|
|
mnode[node].tw = mnode[node].tw > 0 ? mnode[node].tw + wins : wins
|
|
mnode[node].wins = 0
|
|
mnode[node].ty = mnode[node].ty > 0 ? mnode[node].ty + mnode[node].yays : mnode[node].yays
|
|
mnode[node].yays = 0
|
|
const gbal = gov[node] || 0
|
|
const feevote = mnode[node].bidRate > 1000 || mnode[node].bidRate < 0 || typeof mnode[node].bidRate != 'number' ? 1000 : mnode[node].bidRate
|
|
const dmvote = typeof mnode[node].dm != 'number' ? 10000 : mnode[node].dm
|
|
const dsvote = typeof mnode[node].ds != 'number' ? 0 : mnode[node].ds
|
|
const dvvote = typeof mnode[node].dv != 'number' ? 1500 : mnode[node].dv
|
|
mnode[node].ds = dsvote
|
|
mnode[node].dm = dmvote
|
|
dexfeea += parseInt(wins * gbal * feevote);
|
|
dexfeed += parseInt(wins * gbal * 1000);
|
|
dexmaxa += parseInt(wins * gbal * dmvote);
|
|
dexmaxd += parseInt(wins * gbal * 10000);
|
|
dexslopea += parseInt(wins * gbal * dsvote);
|
|
dexsloped += parseInt(wins * gbal * 10000);
|
|
dva += parseInt(wins * gbal * dvvote);
|
|
dvd += parseInt(wins * gbal * 10000);
|
|
i = parseInt(wins / j * b);
|
|
cbals[node] = cbals[node] ? cbals[node] += i : cbals[node] = i;
|
|
bals.rn -= i;
|
|
const _at = _atfun(node);
|
|
if (i) {
|
|
post = post + `* ${_at}${node} awarded ${parseFloat(i / 1000).toFixed(3)} ${config.TOKEN} for ${wins} credited transaction(s)\n`;
|
|
console.log(num + `:@${node} awarded ${parseFloat(i / 1000).toFixed(3)} ${config.TOKEN} for ${wins} credited transaction(s)`);
|
|
}
|
|
}
|
|
}
|
|
stats.dex_fee = parseFloat((dexfeea / dexfeed)/100).toFixed(5);
|
|
stats.dex_max = parseFloat((dexmaxa / dexmaxd)*100).toFixed(2);
|
|
stats.dex_slope = parseFloat((dexslopea / dexsloped)*100).toFixed(2);
|
|
stats.daoclaim.v = parseInt(dva / dvd);
|
|
for(var node in newOwners){
|
|
newOwners[node].g = runners[node]?.g ? runners[node].g : 0;
|
|
}
|
|
var up_op = accountUpdate( stats, mnode, pick(newOwners) )
|
|
function pick(noobj){
|
|
var top = 0
|
|
var topwin = 0
|
|
var tops = []
|
|
for (var node in noobj){
|
|
if(noobj[node].g > top){
|
|
top = noobj[node].g
|
|
}
|
|
if(noobj[node].wins > topwin){
|
|
topwin = noobj[node].wins
|
|
}
|
|
if(noobj[node].wins)tops.push(noobj[node].g )
|
|
}
|
|
tops.sort((a,b)=>{return b-a})
|
|
var thresh = tops[parseInt(tops.length/2) - 1]
|
|
var sorting = [], out = []
|
|
for (var node in noobj){
|
|
if(noobj[node].g >= thresh && noobj[node].wins >= (topwin * 90 / 100)){
|
|
sorting.push({node, g: noobj[node].g})
|
|
}
|
|
}
|
|
sorting.sort((a,b)=>{return b.g - a.g})
|
|
for (var i = 0; i < sorting.length; i++){
|
|
out.push(sorting[i].node)
|
|
}
|
|
return out
|
|
}
|
|
bals.rd += parseInt(t * stats.delegationRate / 10000); // 10% to delegators
|
|
if(config.features.delegate){
|
|
post = post + `### ${parseFloat(parseInt(bals.rd) / 1000).toFixed(3)} ${config.TOKEN} set aside for @${config.delegation} delegators\n`;
|
|
bals.ra -= parseInt(t * stats.delegationRate / 10000);
|
|
b = bals.rd;
|
|
j = 0;
|
|
console.log(num + `:${b} ${config.TOKEN} to distribute to delegators`);
|
|
for (i in deles) { //count vests
|
|
j += deles[i];
|
|
}
|
|
for (i in deles) { //reward vests
|
|
k = parseInt(b * deles[i] / j);
|
|
cbals[i] ? cbals[i] += k : cbals[i] = k;
|
|
bals.rd -= k;
|
|
const _at = _atfun(i);
|
|
post = post + `* ${parseFloat(parseInt(k) / 1000).toFixed(3)} ${config.TOKEN} for ${_at}${i}'s ${parseFloat(deles[i] / 1000000).toFixed(1)} Mvests.\n`;
|
|
console.log(num + `:${k} ${config.TOKEN} awarded to ${i} for ${deles[i]} VESTS`);
|
|
}
|
|
stats[`${config.jsonTokenName}PerDel`] = parseFloat(k / j).toFixed(6);
|
|
}
|
|
if(config.features.ico){
|
|
post = post + `*****\n ## ICO Status\n`;
|
|
if (bals.ri < 100000000 && stats.tokenSupply < 100000000000) {
|
|
stats.icoRound++;
|
|
if (bals.ri == 0) {
|
|
stats.tokenSupply += 100000000;
|
|
bals.ri = 100000000;
|
|
var ago = num - stats.outOnBlock,
|
|
dil = ' seconds';
|
|
if (ago !== num) {
|
|
bals.rl = parseInt(ago / 30240 * 50000000);
|
|
bals.ri = 100000000 - parseInt(ago / 30240 * 50000000);
|
|
stats.icoPrice = stats.icoPrice * (1 + (ago / 30240) / 2);
|
|
}
|
|
if (ago > 20) {
|
|
dil = ' minutes';
|
|
ago = parseFloat(ago / 20)
|
|
.toFixed(1);
|
|
} else {
|
|
ago = ago * 3;
|
|
}
|
|
if (ago > 60) {
|
|
dil = ' hours';
|
|
ago = parseFloat(ago / 60)
|
|
.toFixed(1);
|
|
}
|
|
post = post + `### We sold out ${ago}${dil}\nThere are now ${parseFloat(bals.ri / 1000).toFixed(3)} ${config.TOKEN} for sale from @${config.mainICO} for ${parseFloat(stats.icoPrice / 1000).toFixed(3)} HIVE each.\n`;
|
|
} else {
|
|
var left = bals.ri;
|
|
stats.tokenSupply += 100000000 - left;
|
|
bals.ri = 100000000;
|
|
stats.icoPrice = stats.icoPrice - (left / 1000000000); //10% max decrease
|
|
if (stats.icoPrice < 1000)
|
|
stats.icoPrice = 1000;
|
|
post = post + `### We Sold out ${100000000 - left} today.\nThere are now ${parseFloat(bals.ri / 1000).toFixed(3)} ${config.TOKEN} for sale from @${config.mainICO} for ${parseFloat(stats.icoPrice / 1000).toFixed(3)} HIVE each.\n`;
|
|
}
|
|
} else {
|
|
post = post + `### We have ${parseFloat(parseInt(bals.ri - 100000000) / 1000).toFixed(3)} ${config.TOKEN} left for sale at ${parseFloat(stats.icoPrice / 1000).toFixed(3)} HIVE in our Pre-ICO. Send your HIVE to @${config.mainICO} to own a piece of the community.\n`;
|
|
}
|
|
if (bals.rl) {
|
|
var dailyICODistrobution = bals.rl,
|
|
y = 0;
|
|
for (i = 0; i < ico.length; i++) {
|
|
for (var node in ico[i]) {
|
|
y += ico[i][node];
|
|
}
|
|
}
|
|
post = post + `### ICO Over Auction Results:\n${parseFloat(bals.rl / 1000).toFixed(3)} ${config.TOKEN} was set aside from today's ICO to divide between people who didn't get a chance at fixed price tokens and donated ${parseFloat(y / 1000).toFixed(3)} HIVE today.\n`;
|
|
for (i = 0; i < ico.length; i++) {
|
|
for (var node in ico[i]) {
|
|
cbals[node] ? cbals[node] += parseInt(ico[i][node] / y * bals.rl) : cbals[node] = parseInt(ico[i][node] / y * bals.rl);
|
|
dailyICODistrobution -= parseInt(ico[i][node] / y * bals.rl);
|
|
post = post + `* @${node} awarded ${parseFloat(parseInt(ico[i][node] / y * bals.rl) / 1000).toFixed(3)} ${config.TOKEN} for ICO auction\n`;
|
|
console.log(num + `:${node} awarded ${parseInt(ico[i][node] / y * bals.rl)} ${config.TOKEN} for ICO auction`);
|
|
if (i == ico.length - 1) {
|
|
cbals[node] ? cbals[node] += dailyICODistrobution : cbals[node] = dailyICODistrobution
|
|
post = post + `* @${node} awarded ${parseFloat(parseInt(dailyICODistrobution) / 1000).toFixed(3)} ${config.TOKEN} for ICO auction\n`;
|
|
console.log(num + `:${node} given ${dailyICODistrobution} remainder`);
|
|
}
|
|
}
|
|
}
|
|
bals.rl = 0;
|
|
ico = [];
|
|
}
|
|
}
|
|
var vol = 0,
|
|
volhbd = 0,
|
|
vols = 0,
|
|
his = [],
|
|
hisb = [],
|
|
hi = {},
|
|
hib = {};
|
|
if(config.features.dex){
|
|
for (var int in dex.hive.his) {
|
|
if (dex.hive.his[int].block < num - 60480) {
|
|
his.push(dex.hive.his[int]);
|
|
daops.push({ type: 'del', path: ['dex', 'hive', 'his', int] });
|
|
} else {
|
|
vol += parseInt(dex.hive.his[int].base_vol);
|
|
vols = parseInt(parseInt(dex.hive.his[int].target_vol) + vols);
|
|
}
|
|
}
|
|
for (var int in dex.hbd.his) {
|
|
if (dex.hbd.his[int].block < num - 60480) {
|
|
hisb.push(dex.hbd.his[int]);
|
|
daops.push({ type: 'del', path: ['dex', 'hbd', 'his', int] });
|
|
} else {
|
|
vol += parseInt(dex.hbd.his[int].base_vol);
|
|
volhbd = parseInt(parseInt(dex.hbd.his[int].target_vol) + volhbd);
|
|
}
|
|
}
|
|
if (his.length) {
|
|
hi.o = parseFloat(his[0].price); // open, close, top bottom, dlux, volumepair
|
|
hi.c = parseFloat(his[his.length - 1].price);
|
|
hi.t = 0;
|
|
hi.b = hi.o;
|
|
hi.d = 0;
|
|
hi.v = 0;
|
|
for (var int = 0; int < his.length; int++) {
|
|
if (hi.t < parseFloat(his[int].price)) {
|
|
hi.t = parseFloat(his[int].price);
|
|
}
|
|
if (hi.b > parseFloat(his[int].price)) {
|
|
hi.b = parseFloat(his[int].price);
|
|
}
|
|
|
|
hi.v += parseInt(his[int].target_vol);
|
|
hi.d += parseInt(his[int].base_vol);
|
|
}
|
|
if (!dex.hive.days)
|
|
dex.hive.days = {};
|
|
dex.hive.days[num] = hi;
|
|
}
|
|
if (hisb.length) {
|
|
hib.o = parseFloat(hisb[0].price); // open, close, top bottom, dlux, volumepair
|
|
hib.c = parseFloat(hisb[hisb.length - 1].price);
|
|
hib.t = 0;
|
|
hib.b = hib.o;
|
|
hib.v = 0;
|
|
hib.d = 0;
|
|
for (var int = 0; int < hisb.length; int++) {
|
|
if (hib.t < parseFloat(hisb[int].price)) {
|
|
hib.t = parseFloat(hisb[int].price);
|
|
}
|
|
if (hib.b > parseFloat(hisb[int].price)) {
|
|
hib.b = parseFloat(hisb[int].price);
|
|
}
|
|
hib.v += parseInt(hisb[int].target_vol);
|
|
hib.d += parseInt(hisb[int].base_vol);
|
|
}
|
|
if (!dex.hbd.days)
|
|
dex.hbd.days = {};
|
|
dex.hbd.days[num] = hib;
|
|
}
|
|
let liqt = config.features.liquidity ? parseInt((bals.rm/365)*(stats.liq_reward/100)) : 0
|
|
if (liqt > 0){
|
|
let liqa = 0
|
|
for (var acc in dex.liq){
|
|
liqa += parseInt(dex.liq[acc])
|
|
}
|
|
for (var acc in dex.liq){
|
|
thisd = parseInt(liqt*(dex.liq[acc]/liqa))
|
|
if(!bal[acc])bal[acc] = 0
|
|
bal[acc] += thisd
|
|
bal.rm -= thisd
|
|
}
|
|
}
|
|
delete dex.liq
|
|
daops.push({type: 'del', path: ['dex', 'liq']})
|
|
post = post + `*****\n### DEX Report\n#### Prices:\n* ${parseFloat(dex.hive.tick).toFixed(3)} HIVE per ${config.TOKEN}\n* ${parseFloat(dex.hbd.tick).toFixed(3)} HBD per ${config.TOKEN}\n#### Daily Volume:\n* ${parseFloat(vol / 1000).toFixed(3)} ${config.TOKEN}\n* ${parseFloat(vols / 1000).toFixed(3)} HIVE\n* ${parseFloat(parseInt(volhbd) / 1000).toFixed(3)} HBD\n*****\n`;
|
|
}
|
|
stats.movingWeight.dailyPool = bals.ra
|
|
if(config.features.pob)bals.rc = bals.rc + bals.ra;
|
|
else bals.rn = bals.rn + bals.ra
|
|
bals.ra = 0;
|
|
var q = 0,
|
|
r = bals.rc;
|
|
for (var i in br) {
|
|
q += br[i].post.totalWeight;
|
|
}
|
|
var contentRewards = ``,
|
|
vo = [];
|
|
if (Object.keys(br).length) {
|
|
bucket = parseInt(bals.rc / 200);
|
|
bals.rc = bals.rc - bucket;
|
|
contentRewards = `#### Top Paid Posts\n`;
|
|
const compa = bucket;
|
|
for (var i in br) {
|
|
var dif = bucket;
|
|
for (var j in br[i].post.voters) {
|
|
bals[br[i].post.author] += parseInt((br[i].post.voters[j].weight * 2 / q * 3) * compa);
|
|
cbals[br[i].post.author] ? cbals[br[i].post.author] += parseInt((br[i].post.voters[j].weight * 2 / q * 3) * compa) : cbals[br[i].post.author] = parseInt((br[i].post.voters[j].weight * 2 / q * 3) * compa);
|
|
bucket -= parseInt((br[i].post.voters[j].weight / q * 3) * compa);
|
|
cbals[br[i].post.voters[j].from] ? cbals[br[i].post.voters[j].from] += parseInt((br[i].post.voters[j].weight / q * 3) * compa) : cbals[br[i].post.voters[j].from] = parseInt((br[i].post.voters[j].weight / q * 3) * compa);
|
|
bucket -= parseInt((br[i].post.voters[j].weight * 2 / q * 3) * compa);
|
|
}
|
|
vo.push(br[i].post);
|
|
cpost[i] = {
|
|
v: br[i].post.voters.length,
|
|
d: parseFloat(parseInt(dif - bucket) / 1000).toFixed(3),
|
|
};
|
|
cpost[`s/${br[i].post.author}/${br[i].post.permlink}`] = cpost[i];
|
|
delete cpost[i];
|
|
contentRewards = contentRewards + `* [${br[i].post.title || `${config.TOKEN} Content`}](https://www.${config.mainFE}/@${br[i].post.author}/${br[i].post.permlink}) by @${br[i].post.author} awarded ${parseFloat(parseInt(dif - bucket) / 1000).toFixed(3)} ${config.TOKEN}\n`;
|
|
}
|
|
bals.rc += bucket;
|
|
contentRewards = contentRewards + `\n*****\n`;
|
|
}
|
|
tw = 0,
|
|
ww = 0,
|
|
ii = 100, //max number of votes
|
|
hiveVotes = '';
|
|
for (var po = 0; po < vo.length; po++) {
|
|
tw = tw + vo[po].totalWeight;
|
|
}
|
|
ww = parseInt(tw / 100000);
|
|
vo = sortBuyArray(vo, 'totalWeight');
|
|
if (vo.length < ii)
|
|
ii = vo.length;
|
|
for (var oo = 0; oo < ii; oo++) {
|
|
var weight = parseInt(ww * vo[oo].totalWeight);
|
|
if (weight > 10000)
|
|
weight = 10000;
|
|
daops.push({
|
|
type: 'put',
|
|
path: ['escrow', config.delegation, `vote:${vo[oo].author}:${vo[oo].permlink}`],
|
|
data: [
|
|
"vote", {
|
|
"voter": config.delegation,
|
|
"author": vo[oo].author,
|
|
"permlink": vo[oo].permlink,
|
|
"weight": weight
|
|
}
|
|
]
|
|
});
|
|
cpost[`s/${vo[oo].author}/${vo[oo].permlink}`].b = weight;
|
|
hiveVotes = hiveVotes + `* [${vo[oo].title || `${config.TOKEN} Content`}](https://www.${config.mainFE}/@${vo[oo].author}/${vo[oo].permlink}) by @${vo[oo].author} | ${parseFloat(weight / 100).toFixed(2)}% \n`;
|
|
}
|
|
const footer = `[Visit ${config.mainFE}](https://${config.mainFE})\n[Visit our DEX/Wallet](https://${config.mainFE}/dex)\n[Read LightPaper](/@spknetwork/spk-network-light-paper)\n[Stop @ Mentions - HiveSigner](https://hivesigner.com/sign/custom-json?authority=posting&required_auths=0&id=${config.prefix}nomention&json=%7B%22nomention%22%3Atrue%7D)\n${config.footer}`;
|
|
if (hiveVotes)
|
|
hiveVotes = `#### Community Voted ${config.TOKEN} Posts\n` + hiveVotes + `*****\n`;
|
|
post = header + contentRewards + hiveVotes + post + footer;
|
|
var op = ["comment",
|
|
{
|
|
"parent_author": "",
|
|
"parent_permlink": config.tag,
|
|
"author": config.leader,
|
|
"permlink": config.tag + num,
|
|
"title": `${config.TOKEN} DAO | Block Report ${num}`,
|
|
"body": post,
|
|
"json_metadata": JSON.stringify({
|
|
tags: [config.tag]
|
|
})
|
|
}
|
|
];
|
|
if(up_op){
|
|
daops.push({ type: 'del', path: ['mso']});
|
|
daops.push({ type: 'put', path: ['mso', `${num}:ac`], data: stringify(['account_update', up_op]) });
|
|
}
|
|
daops.push({ type: 'put', path: ['dex'], data: dex });
|
|
daops.push({ type: 'put', path: ['stats'], data: stats });
|
|
daops.push({ type: 'put', path: ['balances'], data: bals });
|
|
daops.push({ type: 'put', path: ['cbalances'], data: cbals });
|
|
daops.push({ type: 'put', path: ['posts'], data: cpost });
|
|
daops.push({ type: 'put', path: ['markets', 'node'], data: mnode });
|
|
daops.push({ type: 'put', path: ['delegations'], data: deles });
|
|
if(config.features.daily)daops.push({ type: 'put', path: ['escrow', config.leader, 'comment'], data: stringify(op) });
|
|
for (var i = daops.length - 1; i >= 0; i--) {
|
|
if (daops[i].type == 'put' && Object.keys(daops[i].data).length == 0 && typeof daops[i].data != 'number' && typeof daops[i].data != 'string') {
|
|
daops.splice(i, 1);
|
|
}
|
|
}
|
|
for (var bali in bals) {
|
|
if(bals[bali] == 0 && bali.length > 2) {
|
|
daops.push({ type: 'del', path: ['balances', bali] });
|
|
}
|
|
}
|
|
store.batch(daops, [resolve, reject, num]);
|
|
});
|
|
});
|
|
}
|
|
|
|
exports.dao = dao;
|
|
|
|
function Distro(){
|
|
return new Promise ((resolve, reject)=>{
|
|
let Pbals = getPathObj(['balances']),
|
|
Psets = getPathObj(['sets']),
|
|
Pdiv = getPathObj(['div'])
|
|
Promise.all([Pbals, Psets, Pdiv]).then(mem =>{
|
|
let ops = [],
|
|
bals = mem[0],
|
|
sets = mem[1],
|
|
div = mem[2],
|
|
out = []
|
|
for(var acc in bals) {
|
|
if(acc.split('n:')[1]) {
|
|
out = [...out, ...preadd(bals[acc], sets[acc.split(':')[1]]), [acc, - bals[acc]]]
|
|
}
|
|
}
|
|
out.sort((a, b) => a[0] - b[0])
|
|
for(var i = 0; i < out.length - 1; i++) {
|
|
if (out[i][0] == out[i + 1][0]) {
|
|
out[i+1][1] = out[i][1] + out[i+1][1]
|
|
out.splice(i, 1)
|
|
i--
|
|
}
|
|
}
|
|
resolve(out)
|
|
})
|
|
})
|
|
function preadd (bal, set){
|
|
if(set.ra){
|
|
let ret = [],
|
|
accounts = set.ra.split(',')
|
|
out = 0
|
|
for (var i = 0; i < accounts.length - 1; i++) {
|
|
t = parseInt((bal*accounts[i].split('_')[1])/10000)
|
|
out += t
|
|
ret.push([accounts[i].split('_')[0] == 'd' ? `div:${set.n}` : accounts[i].split('_')[0], t])
|
|
}
|
|
ret.push([accounts[accounts.length - 1].split('_')[0] == 'd' ? `div:${set.n}` : accounts[i].split('_')[0], bal - out])
|
|
return ret
|
|
} else {
|
|
return [[set.a, bal]]
|
|
}
|
|
}
|
|
}
|
|
|
|
exports.Distro = Distro;
|
|
|
|
function Liquidity(){
|
|
return new Promise ((resolve, reject)=>{
|
|
let Pmarket = getPathObj(['dex'])
|
|
Promise.all([Pmarket]).then(mem =>{
|
|
let m = mem[0],
|
|
hiveh = parseFloat(m.hive.buyBook.split('_')[0]),
|
|
hbdh = parseFloat(m.hbd.buyBook.split('_')[0]),
|
|
awards = {}
|
|
if(!m.liq)m.liq = {}
|
|
for (var item in m.hive.buyOrders){
|
|
const acc = m.hive.buyOrders[item].from
|
|
if(!awards[acc]) awards[acc] = 0
|
|
awards[acc] += parseInt((parseFloat(m.hive.buyOrders[item].rate)/hiveh)*m.hive.buyOrders[item].hive)
|
|
}
|
|
for (var item in m.hbd.buyOrders){
|
|
const acc = m.hbd.buyOrders[item].from
|
|
if(!awards[acc]) awards[acc] = 0
|
|
awards[acc] += parseInt((parseFloat(m.hbd.buyOrders[item].rate)/hbdh)*m.hbd.buyOrders[item].hbd)
|
|
}
|
|
for(var acc in awards) {
|
|
if(!m.liq[acc])m.liq[acc] = 0
|
|
m.liq[acc] += awards[acc]
|
|
}
|
|
if(Object.keys(m.liq).length)store.batch([{type: 'put', path: ['dex', 'liq'], data: m.liq}],[resolve, reject, 'liq_compound'])
|
|
else resolve('no liq')
|
|
})
|
|
})
|
|
}
|
|
exports.Liquidity = Liquidity;
|
|
|
|
function accountUpdate(stats, nodes, arr){
|
|
//get runners by gov balance
|
|
//find highest three that also have a public key
|
|
for (var i = 0; i < arr.length; i++) { //must have ms keys
|
|
if(!nodes[arr[i]].mskey){
|
|
arr.splice(i, 1)
|
|
i--
|
|
}
|
|
}
|
|
var differrent = false
|
|
var same = true
|
|
var current = 0
|
|
Object.keys(stats.ms.active_account_auths).forEach(function(key) {
|
|
if(arr.indexOf(key) == -1) {
|
|
same = false
|
|
current++
|
|
}
|
|
})
|
|
for (var i = 0; i < arr.length; i++) {
|
|
if(stats.ms.active_account_auths[arr[i]] != 1)differrent = true
|
|
}
|
|
if((same && current >= 3) || !differrent || arr.length < 2)return
|
|
if(arr.length > 3)arr = [arr[0], arr[1], arr[2]]
|
|
var updateOp = {
|
|
"account": config.msaccount,
|
|
"active": {
|
|
"weight_threshold": parseInt(arr.length/2 + 1),
|
|
"account_auths": [],
|
|
"key_auths": []
|
|
},
|
|
"owner": {
|
|
"weight_threshold": parseInt(arr.length/2 + 1),
|
|
"account_auths": [],
|
|
"key_auths": []
|
|
},
|
|
"posting": {
|
|
"weight_threshold": 1,
|
|
"account_auths": [[config.leader, 1]],
|
|
"key_auths": []
|
|
},
|
|
"memo_key": config.msPubMemo,
|
|
"json_metadata": stringify(config.msmeta)
|
|
}
|
|
for (var i = 0; i < arr.length; i++) {
|
|
updateOp.active.account_auths.push([arr[i], 1])
|
|
updateOp.owner.key_auths.push([nodes[arr[i]].mskey, 1])
|
|
}
|
|
return updateOp
|
|
}
|