_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); $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; } 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; } } }