296 lines
10 KiB
PHP
296 lines
10 KiB
PHP
<?php
|
|
|
|
namespace models;
|
|
|
|
require_once("mt/Staking.php");
|
|
|
|
require_once("models/User.php");
|
|
|
|
use phpcommon\SqlHelper;
|
|
|
|
use mt;
|
|
|
|
class Staking extends BaseModel {
|
|
|
|
const STAKING_STATUS = 0;
|
|
const REDEEM_STATUS = 1;
|
|
|
|
const NFT721 = 1;
|
|
|
|
public static function all($address)
|
|
{
|
|
$result = array();
|
|
$rows = SqlHelper::ormSelect(
|
|
myself()->_getMysql(''),
|
|
't_staking',
|
|
array(
|
|
'address' => $address
|
|
)
|
|
);
|
|
foreach ($rows as $row) {
|
|
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['ceg_value'];
|
|
}
|
|
}
|
|
}
|
|
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']
|
|
);
|
|
$passedDays = intval(((myself()->_getNowDaySeconds() + 3600 * 24) -
|
|
myself()->_getDaySeconds($row['start_time'])) /
|
|
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']);
|
|
$srcDailyInterest = $dailyInterest;
|
|
if ($saveDays >= 30 * 12 * 2) {
|
|
if ($stakedDays < 30 * 12) {
|
|
$dailyInterest *= 0.6;
|
|
} else {
|
|
$dailyInterest *= 0.4;
|
|
}
|
|
}
|
|
$dto['daily_rewards'] = $dto['cec_value'] * $dailyInterest;
|
|
/*
|
|
error_log(json_encode(array(
|
|
'remain_days' => max(0, $saveDays - $dto['stacked_days']),
|
|
'daily_rewards' => $dto['daily_rewards'],
|
|
'daily_interest' => $dailyInterest
|
|
)));
|
|
*/
|
|
$srcDailyRewards = $dto['cec_value'] * $srcDailyInterest;
|
|
$dto['cec_rewards'] = 0;
|
|
$dto['total_rewards'] = 0;
|
|
if ($dto['status'] == self::REDEEM_STATUS) {
|
|
$stakedDays = intval(($dto['redeem_time'] - myself()->_getDaySeconds($row['start_time']) - 3600 * 24) / 3600 / 24);
|
|
$stakedDays = max($stakedDays, 0);
|
|
$stakedDays = min($stakedDays, $saveDays);
|
|
if ($saveDays >= 30 * 12 * 2) {
|
|
$stakedDays = max($stakedDays, 0);
|
|
$dto['cec_rewards'] = $srcDailyRewards * min(30 * 12, $stakedDays) * 0.6 * 0.25;
|
|
$dto['cec_rewards'] += $srcDailyRewards * max(0, $stakedDays - 30 * 12) * 0.4 * 0.25;
|
|
} else {
|
|
$dto['cec_rewards'] = $srcDailyRewards * $stakedDays * 0.25;
|
|
}
|
|
$dto['total_rewards'] = $dto['cec_rewards'];
|
|
} else {
|
|
$stakedDays = max($stakedDays, 0);
|
|
$stakedDays = min($stakedDays, $saveDays);
|
|
if ($dto['remain_days'] <= 0 ) {
|
|
$dto['cec_rewards'] = $srcDailyRewards * $stakedDays;
|
|
} else {
|
|
if ($saveDays >= 30 * 12 * 2) {
|
|
$dto['cec_rewards'] = $srcDailyRewards * min(30 * 12, $stakedDays) * 0.6;
|
|
$dto['cec_rewards'] += $srcDailyRewards * max(0, $stakedDays - 30 * 12) * 0.4;
|
|
} 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) {
|
|
return 1 / 30 / $months;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
}
|