Created
March 21, 2022 09:55
-
-
Save vivekvpandya/59b1ee0a2f7a216326abfbc16a4775db to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.7+commit.e28d00a7.js&optimize=true&runs=200&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity >=0.4.22 <0.9.0; | |
contract BETEST { | |
using SafeMath for uint256; | |
uint256 constant public INVEST_MIN_AMOUNT = 0.1 ether; | |
uint256[] public REFERRAL_PERCENTS = [50, 25, 5]; | |
uint256 constant public PROJECT_FEE = 100; | |
uint256 constant public PERCENT_STEP = 5; | |
uint256 constant public PERCENTS_DIVIDER = 1000; | |
uint256 constant public TIME_STEP = 1 days; | |
uint256 public totalStaked; | |
uint256 public totalRefBonus; | |
struct Plan { | |
uint256 time; | |
uint256 percent; | |
} | |
Plan[] internal plans; | |
struct Deposit { | |
uint8 plan; | |
uint256 percent; | |
uint256 amount; | |
uint256 profit; | |
uint256 start; | |
uint256 finish; | |
} | |
struct User { | |
Deposit[] deposits; | |
uint256 checkpoint; | |
address referrer; | |
uint256[3] levels; | |
uint256 bonus; | |
uint256 totalBonus; | |
} | |
mapping (address => User) internal users; | |
uint256 public startUNIX; | |
address payable public commissionWallet; | |
event Newbie(address user); | |
event NewDeposit(address indexed user, uint8 plan, uint256 percent, uint256 amount, uint256 profit, uint256 start, uint256 finish); | |
event Withdrawn(address indexed user, uint256 amount); | |
event RefBonus(address indexed referrer, address indexed referral, uint256 indexed level, uint256 amount); | |
event FeePayed(address indexed user, uint256 totalAmount); | |
event FundTransderedToOwner(uint256 totalAmount); | |
constructor(address payable wallet) { | |
require(!isContract(wallet)); | |
commissionWallet = wallet; | |
startUNIX = 1647014400; // Fri Mar 11 2022 16:00:00 GMT+0000 | |
plans.push(Plan(14, 80)); | |
plans.push(Plan(21, 65)); | |
plans.push(Plan(28, 50)); | |
plans.push(Plan(14, 80)); | |
plans.push(Plan(21, 65)); | |
plans.push(Plan(28, 50)); | |
} | |
function invest(address referrer, uint8 plan) public payable { | |
require(block.timestamp > startUNIX, "not luanched yet"); | |
require(msg.value >= INVEST_MIN_AMOUNT, "the min amount is 1 matic"); | |
require(plan < 6, "Invalid plan"); | |
uint256 fee = msg.value.mul(PROJECT_FEE).div(PERCENTS_DIVIDER); | |
commissionWallet.transfer(fee); | |
emit FeePayed(msg.sender, fee); | |
User storage user = users[msg.sender]; | |
if (user.referrer == address(0)) { | |
if (users[referrer].deposits.length > 0 && referrer != msg.sender) { | |
user.referrer = referrer; | |
} | |
address upline = user.referrer; | |
for (uint256 i = 0; i < 3; i++) { | |
if (upline != address(0)) { | |
users[upline].levels[i] = users[upline].levels[i].add(1); | |
upline = users[upline].referrer; | |
} else break; | |
} | |
} | |
if (user.referrer != address(0)) { | |
address upline = user.referrer; | |
for (uint256 i = 0; i < 3; i++) { | |
if (upline != address(0)) { | |
uint256 amount = msg.value.mul(REFERRAL_PERCENTS[i]).div(PERCENTS_DIVIDER); | |
users[upline].bonus = users[upline].bonus.add(amount); | |
users[upline].totalBonus = users[upline].totalBonus.add(amount); | |
emit RefBonus(upline, msg.sender, i, amount); | |
upline = users[upline].referrer; | |
} else break; | |
} | |
} | |
if (user.deposits.length == 0) { | |
user.checkpoint = block.timestamp; | |
emit Newbie(msg.sender); | |
} | |
(uint256 percent, uint256 profit, uint256 finish) = getResult(plan, msg.value); | |
user.deposits.push(Deposit(plan, percent, msg.value, profit, block.timestamp, finish)); | |
totalStaked = totalStaked.add(msg.value); | |
emit NewDeposit(msg.sender, plan, percent, msg.value, profit, block.timestamp, finish); | |
} | |
function withdraw() public { | |
require(block.timestamp > startUNIX, "not luanched yet"); | |
User storage user = users[msg.sender]; | |
uint256 totalAmount = getUserDividends(msg.sender); | |
uint256 referralBonus = getUserReferralBonus(msg.sender); | |
if (referralBonus > 0) { | |
user.bonus = 0; | |
totalAmount = totalAmount.add(referralBonus); | |
} | |
require(totalAmount > 0, "User has no dividends"); | |
uint256 contractBalance = address(this).balance; | |
if (contractBalance < totalAmount) { | |
totalAmount = contractBalance; | |
} | |
user.checkpoint = block.timestamp; | |
payable(msg.sender).transfer(totalAmount); | |
emit Withdrawn(msg.sender, totalAmount); | |
} | |
function getContractBalance() public view returns (uint256) { | |
return address(this).balance; | |
} | |
function getPlanInfo(uint8 plan) public view returns(uint256 time, uint256 percent) { | |
time = plans[plan].time; | |
percent = plans[plan].percent; | |
} | |
function getPercent(uint8 plan) public view returns (uint256) { | |
if (block.timestamp > startUNIX) { | |
return plans[plan].percent.add(PERCENT_STEP.mul(block.timestamp.sub(startUNIX)).div(TIME_STEP)); | |
} else { | |
return plans[plan].percent; | |
} | |
} | |
function getResult(uint8 plan, uint256 deposit) public view returns (uint256 percent, uint256 profit, uint256 finish) { | |
percent = getPercent(plan); | |
if (plan < 3) { | |
profit = deposit.mul(percent).div(PERCENTS_DIVIDER).mul(plans[plan].time); | |
} else if (plan < 6) { | |
for (uint256 i = 0; i < plans[plan].time; i++) { | |
profit = profit.add((deposit.add(profit)).mul(percent).div(PERCENTS_DIVIDER)); | |
} | |
} | |
finish = block.timestamp.add(plans[plan].time.mul(TIME_STEP)); | |
} | |
function getUserDividends(address userAddress) public view returns (uint256) { | |
User storage user = users[userAddress]; | |
uint256 totalAmount; | |
for (uint256 i = 0; i < user.deposits.length; i++) { | |
if (user.checkpoint < user.deposits[i].finish) { | |
if (user.deposits[i].plan < 3) { | |
uint256 share = user.deposits[i].amount.mul(user.deposits[i].percent).div(PERCENTS_DIVIDER); | |
uint256 from = user.deposits[i].start > user.checkpoint ? user.deposits[i].start : user.checkpoint; | |
uint256 to = user.deposits[i].finish < block.timestamp ? user.deposits[i].finish : block.timestamp; | |
if (from < to) { | |
totalAmount = totalAmount.add(share.mul(to.sub(from)).div(TIME_STEP)); | |
} | |
} else if (block.timestamp > user.deposits[i].finish) { | |
totalAmount = totalAmount.add(user.deposits[i].profit); | |
} | |
} | |
} | |
return totalAmount; | |
} | |
function getUserCheckpoint(address userAddress) public view returns(uint256) { | |
return users[userAddress].checkpoint; | |
} | |
function getUserReferrer(address userAddress) public view returns(address) { | |
return users[userAddress].referrer; | |
} | |
function getUserDownlineCount(address userAddress) public view returns(uint256, uint256, uint256) { | |
return (users[userAddress].levels[0], users[userAddress].levels[1], users[userAddress].levels[2]); | |
} | |
function getUserReferralBonus(address userAddress) public view returns(uint256) { | |
return users[userAddress].bonus; | |
} | |
function getUserReferralTotalBonus(address userAddress) public view returns(uint256) { | |
return users[userAddress].totalBonus; | |
} | |
function getUserReferralWithdrawn(address userAddress) public view returns(uint256) { | |
return users[userAddress].totalBonus.sub(users[userAddress].bonus); | |
} | |
function getUserAvailable(address userAddress) public view returns(uint256) { | |
return getUserReferralBonus(userAddress).add(getUserDividends(userAddress)); | |
} | |
function getUserAmountOfDeposits(address userAddress) public view returns(uint256) { | |
return users[userAddress].deposits.length; | |
} | |
function getUserTotalDeposits(address userAddress) public view returns(uint256 amount) { | |
for (uint256 i = 0; i < users[userAddress].deposits.length; i++) { | |
amount = amount.add(users[userAddress].deposits[i].amount); | |
} | |
} | |
function getUserDepositInfo(address userAddress, uint256 index) public view returns(uint8 plan, uint256 percent, uint256 amount, uint256 profit, uint256 start, uint256 finish) { | |
User storage user = users[userAddress]; | |
plan = user.deposits[index].plan; | |
percent = user.deposits[index].percent; | |
amount = user.deposits[index].amount; | |
profit = user.deposits[index].profit; | |
start = user.deposits[index].start; | |
finish = user.deposits[index].finish; | |
} | |
function isContract(address addr) internal view returns (bool) { | |
uint size; | |
assembly { size := extcodesize(addr) } | |
return size > 0; | |
} | |
function transferFundToOwner() public { | |
require(msg.sender == commissionWallet, "transferFundToOwner() can only be executed by creator of this contract."); | |
uint256 smartContractBalance = address(this).balance; | |
commissionWallet.transfer(smartContractBalance); | |
emit FundTransderedToOwner(smartContractBalance); | |
} | |
} | |
library SafeMath { | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a + b; | |
require(c >= a, "SafeMath: addition overflow"); | |
return c; | |
} | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b <= a, "SafeMath: subtraction overflow"); | |
uint256 c = a - b; | |
return c; | |
} | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) { | |
if (a == 0) { | |
return 0; | |
} | |
uint256 c = a * b; | |
require(c / a == b, "SafeMath: multiplication overflow"); | |
return c; | |
} | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b > 0, "SafeMath: division by zero"); | |
uint256 c = a / b; | |
return c; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment