coinwind/app/Console/Commands/CoinCalc.php

273 lines
7.2 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Balance;
use App\Base;
use App\Http\Controllers\ApiV1Controller;
use App\Single;
use App\Staking;
use App\User;
use App\Vault3;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
/**
* 计算
*/
class CoinCalc extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'coin:calc';
/**
* The console command description.
*
* @var string
*/
protected $description = "Calculating user's profits who deposited.";
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* 获取配置
*/
protected function _get_staking_plans()
{
$rows = Single::where('type', Base::SINGLE_TYPE_FLUIDITY)
->get()->toArray();
$plans = [];
foreach ($rows as $row) {
if ($row['conf']) {
$plans[$row['name']] = json_decode($row['conf'], true)['plans'];
}
}
// var_dump($plans);
return $plans;
}
/**
* calculate profit by money and plan
*
* @deposited: how much have deposited.
* @plan: the relative staking plan.
*/
protected function _calc_income($deposited, $plan)
{
foreach ($plan as $p) {
if ($deposited >= $p['min'] && $deposited <= $p['max']) {
$rate = bcdiv($p['interest'], 100, 4);
return floatval(bcmul($rate, $deposited, 4));
}
}
return 0.0;
}
protected function _calc_income_lr($deposited, $plan)
{
foreach ($plan as $p) {
if ($deposited >= $p['min'] && $deposited <= $p['max']) {
$micro = bcdiv($p['rr'] - $p['rl'], ($p['max'] - $p['min']), 8);
$rate = bcmul($micro, ($deposited - $p['min']), 8) + $p['ll'];
$profit = bcdiv(bcmul($rate, $deposited, 8), 100, 4);
return $profit;
}
}
return 0.0;
}
/**
* Execute the command.
* coin:calc
*
* @return mixed
*/
public function handle()
{
(new CoinInit())->refresh_eth_cache();
$this->_daily_revenue_lr();
$this->_pool_data();
$this->_robots();
}
protected function _daily_revenue_usdt()
{
// get plan
$plans = $this->_get_staking_plans();
$investors = User::where('balance', '>', 0)
->get()
->toArray();
$log = [];
foreach ($investors as $inve) {
$profit = $this->_calc_income($inve['balance'], $plans[Base::USDT]);
$profit = Base::ffixed($profit, 4);
if ($profit > 0) {
$suc = DB::transaction(function () use ($inve, $profit) {
User::where('id', $inve['id'])->increment('balance', $profit);
//
$newBlc = new Balance();
$newBlc->address = $inve['address'];
$newBlc->name = Base::USDT;
$newBlc->remake = 'Daily Revenue';
$newBlc->status = Base::BALANCE_STAKING_DAILY_REVENUE;
$newBlc->money = $profit;
$newBlc->created_at = \Carbon\Carbon::now();
$newBlc->save();
});
if (is_null($suc)) {
$log[$inve['address']] = $profit;
}
}
} // foreach
if ($log) {
Log::info('coin:calc executed:' . json_encode($log));
} else {
Log::debug('coin:calc executed');
}
}
/**
* staking earn rate
* 700MH/s~10000MH/s 1%~1.8%
*
* x ~ y a~b
*
* formula :
*
* For any Z between x and y:
*
* P(Z) = Z*((b-a)/(y-x) * (Z-x) + a)/100
*
* Example:
* 800:
* P(800) = 800 * ((1.8-1)/(10000-700) * (800-700) + 1) / 100
* P(9000) = 9000 * ((1.8-1)/(10000-700) *(9000-700) + 1) / 100
*/
protected function _daily_revenue_lr()
{
$conf = [
[
"min" => 700,
"max" => 10000,
"rl" => 1,
'rr' => 1.8,
], [
'min' => 10001,
'max' => 100000,
'rl' => 1.8,
'rr' => 2.2,
], [
'min' => 100001,
'max' => 500000,
'rl' => 2.2,
'rr' => 2.6,
], [
'min' => 500001,
'max' => 1000000,
'rl' => 2.6,
'rr' => 3.05,
], [
'min' => 1000001,
'max' => 5000000,
'rl' => 3.05,
'rr' => 3.5,
],
];
$investors = User::where('balance', '>', 0)
->get()
->toArray();
$log = [];
foreach ($investors as $inve) {
$profit = $this->_calc_income_lr($inve['balance'], $conf);
$profit = Base::ffixed($profit, 4);
if ($profit > 0) {
$suc = DB::transaction(function () use ($inve, $profit) {
User::where('id', $inve['id'])->increment('balance', $profit);
//
$newBlc = new Balance();
$newBlc->address = $inve['address'];
$newBlc->name = Base::USDT;
$newBlc->remake = "Daily Revenue $profit";
$newBlc->status = Base::BALANCE_STAKING_DAILY_REVENUE;
$newBlc->money = $profit;
$newBlc->created_at = \Carbon\Carbon::now();
$newBlc->save();
});
if (is_null($suc)) {
$log[$inve['address']] = $profit;
}
}
} // foreach
if ($log) {
Log::info('coin:calc executed:' . json_encode($log));
} else {
Log::debug('coin:calc executed');
}
}
protected function _pool_data()
{
// string
$s = Redis::get(ApiV1Controller::K_POOLDATA);
// pool data
$pd = json_decode($s, true);
// print_r($pd);
$base = $pd['totalOutput'];
$min = bcmul($base, 0.01, 2);
$max = bcmul($base, 0.1, 2);
$pi = mt_rand($min, $max);
$rd = mt_rand(0, 100);
$pf = $rd / 100;
$pd['totalOutput'] = floatval(bcadd($base, $pi + $pf, 2));
if ($rd < 30) {
$pd['validNode'] += 1;
}
$pd['participant'] += mt_rand(1, 20);
$pd['userRevenue'] = $pd['totalOutput'] - $max;
Redis::set(ApiV1Controller::K_POOLDATA, json_encode($pd));
}
protected function _robots()
{
$all = Redis::hGetAll(ApiV1Controller::K_ROBOTS);
foreach ($all as $k => $v) {
$all[$k] = floatval(bcadd($v, mt_rand(0, $v * 0.16), 2));
}
Redis::hMSet(ApiV1Controller::K_ROBOTS, $all);
}
}