game2006api/webapp/models/Staking.php
aozhiwei 1548872505 1
2024-08-06 16:16:06 +08:00

509 lines
17 KiB
PHP

<?php
namespace models;
require_once("mt/Staking.php");
require_once("models/User.php");
require_once("models/Nft.php");
use phpcommon\SqlHelper;
use mt;
use models\Nft;
class Staking extends BaseModel {
const STAKING_STATUS = 0;
const REDEEM_STATUS = 1;
const NFT721 = 1;
public static function getAllStakingValue()
{
$value = 0;
$rows = SqlHelper::ormSelect(
myself()->_getMysql(''),
't_staking',
array(
'status' => self::STAKING_STATUS
)
);
foreach ($rows as $row) {
if ($row['nft_type'] == self::NFT721) {
if ($row['item_id']) {
$stakingDto = self::toDto($row);
$value += $stakingDto['cec_value'] * (1 + self::getTotalInterest($row['stake_time']));
}
}
}
return $value;
}
public static function all($address)
{
if (SERVER_ENV != _ONLINE) {
//myself()->_setTimeOffset(3600 * 24 * 360 * 2);
}
$result = array();
$rows = SqlHelper::ormSelect(
myself()->_getMysql(''),
't_staking',
array(
'address' => $address
)
);
foreach ($rows as &$row) {
if (SERVER_ENV != _ONLINE) {
if ($row['status'] == self::REDEEM_STATUS) {
$row['redeem_time'] += myself()->_getTimeOffset();
}
}
if ($row['nft_type'] == self::NFT721) {
if (!$row['item_id']) {
$itemId = 0;
$tokenType = 0;
if (!self::repair721NftInfo($row['token_id'], $row['contract_address'], $row['net_id'],
$row['start_time'], $itemId, $tokenType)) {
continue;
}
$row['item_id'] = $itemId;
$row['token_type'] = $tokenType;
}
}
array_push($result, $row);
}
return $result;
}
public static function getStakingTotalValue()
{
$totalValue = 0;
$rows = self::all(myself()->_getAddress());
foreach ($rows as $row) {
$stakingDto = self::toDto($row);
if ($stakingDto['status'] == self::STAKING_STATUS) {
if ($stakingDto['remain_days'] > 0) {
$totalValue += $stakingDto['stake_usd_value'];
} else {
}
}
}
if (SERVER_ENV != _ONLINE) {
myself()->_setTimeOffset(0);
}
return $totalValue;
}
public static function staked721($data, $netId)
{
foreach ($data['infos'] as $info) {
$address = strtolower($info[0]);
$nftAddress = strtolower($info[1]);
$tokenId = $info[2];
$startTime = $info[3];
$stakeTime = $info[4];
$userDb = User::findByAddress($address);
SqlHelper::upsert(
myself()->_getMysql(''),
't_staking',
array(
'token_id' => $tokenId,
'contract_address' => $nftAddress,
'net_id' => $netId,
'start_time' => $nftAddress,
),
array(
),
array(
'account_id' => $userDb ? $userDb['account_id'] : '',
'address' => $address,
'token_id' => $tokenId,
'token_type' => '0',
'net_id' => $netId,
'contract_address' => $nftAddress,
'stacked_num' => 1,
'start_time' => $startTime,
'stake_time' => $stakeTime,
'status' => self::STAKING_STATUS,
'nft_type' => self::NFT721,
'createtime' => myself()->_getNowTime(),
'modifytime' => myself()->_getNowTime(),
)
);
$itemId = 0;
$tokenType = 0;
self::repair721NftInfo($tokenId, $nftAddress, $netId, $startTime,
$itemId, $tokenId);
}
}
public static function repair721NftInfo($tokenId, $contractAddress, $netId, $startTime,
&$itemId, &$tokenType)
{
$row = SqlHelper::ormSelectOne(
myself()->_getMarketMysql(),
't_nft',
array(
'token_id' => $tokenId,
'contract_address' => $contractAddress,
'net_id' => $netId,
)
);
if (!$row) {
return false;
}
$itemId = $row['item_id'];
$tokenType = $row['token_type'];
SqlHelper::update(
myself()->_getMysql(''),
't_staking',
array(
'token_id' => $tokenId,
'contract_address' => $contractAddress,
'net_id' => $netId,
'start_time' => $startTime,
'nft_type' => self::NFT721,
),
array(
'item_id' => $itemId,
'token_type' => $tokenType
)
);
return true;
}
public static function redeem721($data, $netId, $redeemTime, $txHash)
{
foreach ($data['infos'] as $info) {
$address = strtolower($info[0]);
$nftAddress = strtolower($info[1]);
$tokenId = $info[2];
$startTime = $info[3];
$stakeTime = $info[4];
$userDb = User::findByAddress($address);
SqlHelper::upsert(
myself()->_getMysql(''),
't_staking',
array(
'token_id' => $tokenId,
'contract_address' => $nftAddress,
'net_id' => $netId,
'start_time' => $startTime,
),
array(
'txhash' => $txHash,
'redeem_time' => $redeemTime,
'status' => self::REDEEM_STATUS,
),
array(
'account_id' => $userDb ? $userDb['account_id'] : '',
'address' => $address,
'token_id' => $tokenId,
'token_type' => '0',
'net_id' => $netId,
'contract_address' => $nftAddress,
'stacked_num' => 1,
'start_time' => $startTime,
'stake_time' => $stakeTime,
'txhash' => $txHash,
'redeem_time' => $redeemTime,
'status' => self::REDEEM_STATUS,
'nft_type' => self::NFT721,
'createtime' => myself()->_getNowTime(),
'modifytime' => myself()->_getNowTime(),
)
);
$itemId = 0;
$tokenType = 0;
self::repair721NftInfo($tokenId, $nftAddress, $netId, $startTime,
$itemId, $tokenId);
}
}
public static function toDto($row)
{
$stakingMeta = mt\Staking::get($row['item_id']);
$dto = array(
'trans_id' => $row['idx'],
'token_id' => $row['token_id'],
'token_type' => $row['token_type'],
'contract_address' => $row['contract_address'],
'net_id' => $row['net_id'],
'order_id' => $row['order_id'],
'start_time' => $row['start_time'],
'stake_time' => $row['stake_time'],
'redeem_time' => $row['redeem_time'],
'txhash' => $row['txhash'],
'item_id' => $row['item_id'],
'status' => $row['status'],
'stacked_num' => $row['stacked_num'],
'cec_value' => $stakingMeta['stake_value'],
'stake_usd_value' => $stakingMeta['stake_usd_value'],
);
$passedDays = intval(((myself()->_getNowDaySeconds()) -
(myself()->_getDaySeconds($row['start_time']) + 3600 * 24)) /
3600 / 24);
//这是后面加的
$endTime = getReqVal('end_time', 0);
if ($endTime > 0) {
$passedDays = intval(((myself()->_getDaySeconds($endTime)) -
(myself()->_getDaySeconds($row['start_time']) + 3600 * 24)) /
3600 / 24);
}
$passedDays = max(0, $passedDays);
$saveDays = max(0, intval($row['stake_time'] / 3600 / 24));
$dto['stacked_days'] = $passedDays;
$dto['remain_days'] = max(0, $saveDays - $dto['stacked_days']);
$stakedDays = $dto['stacked_days'];
$dailyInterest = self::getDailyInterest($row['stake_time'], $dto['remain_days']);
$dto['daily_rewards'] = $dto['cec_value'] * $dailyInterest;
$dto['cec_rewards'] = 0;
$dto['total_rewards'] = 0;
if ($dto['status'] == self::REDEEM_STATUS) {
$stakedDays = intval((myself()->_getDaySeconds($dto['redeem_time']) -
(myself()->_getDaySeconds($row['start_time']) + 3600 * 24)) / 3600 / 24);
$stakedDays = max($stakedDays, 0);
$stakedDays = min($stakedDays, $saveDays);
$dto['stacked_days'] = $stakedDays;
/*
if ($dto['stacked_days'] <= 0) {
error_log(json_encode(array(
'src_stacked_days' => $stakedDays,
'now_daySeocnds' => myself()->_getNowDaySeconds(),
'now_time' => myself()->_getNowTime(),
'redeem_time' => myself()->_getDaySeconds($dto['redeem_time'])
)));
}*/
$rate = 0.25;
if ($stakedDays >= $saveDays) {
$rate = 1;
}
$rate = 1;
if ($saveDays >= 30 * 12 * 2) {
$stakedDays = max($stakedDays, 0);
$dto['cec_rewards'] = ($dto['cec_value'] * (0.6 / 30 / 12)) * min(30 * 12, $stakedDays) * $rate;
$dto['cec_rewards'] += ($dto['cec_value'] * (0.4 / 30 / 12)) * max(0, $stakedDays - 30 * 12) * $rate;
} else {
$dto['cec_rewards'] = $dto['daily_rewards'] * $stakedDays * $rate;
}
$dto['total_rewards'] = $dto['cec_rewards'];
} else {
$stakedDays = max($stakedDays, 0);
$stakedDays = min($stakedDays, $saveDays);
if ($dto['remain_days'] <= 0 ) {
$dto['cec_rewards'] = $dto['daily_rewards'] * $stakedDays;
if ($saveDays >= 30 * 12 * 2) {
$dto['cec_rewards'] = $dto['cec_value'] * 1;
}
} else {
if ($saveDays >= 30 * 12 * 2) {
$dto['cec_rewards'] = ($dto['cec_value'] * (0.6 / 30 / 12)) * min(30 * 12, $stakedDays);
$dto['cec_rewards'] += ($dto['cec_value'] * (0.6 / 30 / 12)) * max(0, $stakedDays - 30 * 12);
} else {
$dto['cec_rewards'] = $dto['daily_rewards'] * $stakedDays;
}
}
$dto['total_rewards'] = $dto['cec_rewards'];
}
return $dto;
}
public static function getCecPrice()
{
return 1;
}
private static function getDailyInterest($stakeTime, $remainDays)
{
$months = intval($stakeTime / 3600 / 24 / 30);
if ($months <= 0) {
return 0;
}
//1 3 6 12 24
if ($months <= 1) {
return 0.01 / 30 / $months;
} else if ($months <= 3) {
return 0.05 / 30 / $months;
} else if ($months <= 6) {
return 0.15 / 30 / $months;
} else if ($months <= 12) {
return 0.4 / 30 / $months;
} else if ($months <= 24) {
if ($remainDays > 360) {
return 0.6 / 30 / 12;
} else {
return 0.4 / 30 / 12;
}
} else {
return 0;
}
}
private static function getTotalInterest($stakeTime)
{
$months = intval($stakeTime / 3600 / 24 / 30);
if ($months <= 0) {
return 0;
}
//1 3 6 12 24
if ($months <= 1) {
return 0.01;
} else if ($months <= 3) {
return 0.05;
} else if ($months <= 6) {
return 0.15;
} else if ($months <= 12) {
return 0.4;
} else if ($months <= 24) {
return 1;
} else {
return 0;
}
}
public static function exportStatData()
{
$userHash = array();
$addressHash = self::getAllAddressHash();
$poolSize = 8000 * 10000 - self::getAllStakingValue();
foreach ($addressHash as $key => $val) {
$address = $key;
$rows = $val;
$info = array(
'pool_size' => $poolSize,
'total_staking_value' => '0',
'daily_staking_value' => '0',
'planet' => array(
'type' => self::PLANET_TYPE,
'is_open' => 1
),
'badge' => array(
'type' => self::BADGE_TYPE,
'is_open' => 1
),
'cec' => array(
'type' => self::CEC_TYPE,
'is_open' => 0
),
);
self::fillStakingInfo($info, 'planet', $rows);
self::fillStakingInfo($info, 'badge', $rows);
self::fillStakingInfo($info, 'cec', $rows);
$userHash[$address] = $info['total_staking_value'];
}
return $userHash;
}
private static function fillStakingInfo(&$info, $fieldName, $rows)
{
$stackingInfo = &$info[$fieldName];
$stackingInfo['staked_quant'] = 0;
$stackingInfo['claim_rewards'] = 0;
$stackingInfo['daily_rewards'] = 0;
$stackingInfo['staking_value'] = 0;
$stackingInfo['maturity_quant'] = 0;
foreach ($rows as $row) {
$stakingMeta = mt\Staking::get($row['item_id']);
if (self::isTypeNft($stackingInfo['type'], $row) && $stakingMeta) {
$stakingDto = self::toDto($row);
if ($stakingDto['status'] == self::STAKING_STATUS) {
if ($stakingDto['remain_days'] <= 0) {
$stackingInfo['maturity_quant'] += $stakingDto['stacked_num'];
} else {
$stackingInfo['daily_rewards'] += $stakingDto['daily_rewards'];
$info['daily_staking_value'] += $stakingDto['daily_rewards'];
}
$stackingInfo['staked_quant'] += $stakingDto['stacked_num'];
$stackingInfo['staking_value'] += $stakingDto['cec_value'];
$info['total_staking_value'] += $stakingDto['cec_value'] + $stakingDto['total_rewards'];
} else {
$stackingInfo['claim_rewards'] += $stakingDto['total_rewards'];
//$info['total_staking_value'] += $stakingDto['cec_value'] + $stakingDto['total_rewards'];
}
}
}
}
public static function getAllAddressHash()
{
$rows = SqlHelper::ormSelect(
myself()->_getMysql(''),
't_staking',
array(
)
);
$addressHash = array();
foreach ($rows as &$row) {
if (SERVER_ENV != _ONLINE) {
if ($row['status'] == self::REDEEM_STATUS) {
$row['redeem_time'] += myself()->_getTimeOffset();
}
}
if ($row['nft_type'] == self::NFT721) {
if (!$row['item_id']) {
$itemId = 0;
$tokenType = 0;
if (!self::repair721NftInfo($row['token_id'], $row['contract_address'], $row['net_id'],
$row['start_time'], $itemId, $tokenType)) {
continue;
}
$row['item_id'] = $itemId;
$row['token_type'] = $tokenType;
}
}
if (!array_key_exists($row['address'], $addressHash)) {
$addressHash[$row['address']] = array();
}
array_push($addressHash[$row['address']], $row);
}
return $addressHash;
}
private static function isTypeNft($type, $dbInfo)
{
switch ($type) {
case self::PLANET_TYPE:
{
if (in_array($dbInfo['token_type'], array(
Nft::PLANET_TYPE
))) {
return true;
}
}
break;
case self::BADGE_TYPE:
{
if (SERVER_ENV != _ONLINE) {
if (in_array($dbInfo['token_type'], array(
Nft::HONOR1_TYPE
))) {
return true;
}
} else {
if (in_array($dbInfo['token_type'], array(
Nft::GENESIS_TYPE
))) {
return true;
}
}
}
break;
case self::CEC_TYPE:
{
}
break;
}
return false;
}
const PLANET_TYPE = 1;
const BADGE_TYPE = 2;
const CEC_TYPE = 3;
}