anoxpanda

work in progress

Oct 3rd, 2020
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.05 KB | None | 0 0
  1. pragma solidity 0.5.10;
  2. contract TRONex {
  3. using SafeMath for uint256;
  4. uint256 constant public INVEST_MIN_AMOUNT = 100 trx;
  5. uint256 constant public BASE_PERCENT = 10;
  6. uint256[] public REFERRAL_PERCENTS = [50, 20, 5];
  7. uint256 constant public MARKETING_FEE = 80;
  8. uint256 constant public PROJECT_FEE = 20;
  9. uint256 constant public PERCENTS_DIVIDER = 1000;
  10. uint256 constant public CONTRACT_BALANCE_STEP = 1000000 trx;
  11. uint256 constant public TIME_STEP = 1 days;
  12. uint256 public totalUsers;
  13. uint256 public totalInvested;
  14. uint256 public totalWithdrawn;
  15. uint256 public totalDeposits;
  16. address payable public marketingAddress;
  17. address payable public projectAddress;
  18. struct Deposit {
  19. uint256 amount;
  20. uint256 withdrawn;
  21. uint256 start;
  22. }
  23. struct User {
  24. Deposit[] deposits;
  25. uint256 checkpoint;
  26. address referrer;
  27. uint256 bonus;
  28. }
  29. mapping (address => User) internal users;
  30. event Newbie(address user);
  31. event NewDeposit(address indexed user, uint256 amount);
  32. event Withdrawn(address indexed user, uint256 amount);
  33. event RefBonus(address indexed referrer, address indexed referral, uint256 indexed level, uint256 amount);
  34. event FeePayed(address indexed user, uint256 totalAmount);
  35. constructor(address payable marketingAddr, address payable projectAddr) public {
  36. require(!isContract(marketingAddr) && !isContract(projectAddr));
  37. marketingAddress = marketingAddr;
  38. projectAddress = projectAddr;
  39. }
  40. function invest(address referrer) public payable {
  41. require(msg.value >= INVEST_MIN_AMOUNT);
  42. marketingAddress.transfer(msg.value.mul(MARKETING_FEE).div(PERCENTS_DIVIDER));
  43. projectAddress.transfer(msg.value.mul(PROJECT_FEE).div(PERCENTS_DIVIDER));
  44. emit FeePayed(msg.sender, msg.value.mul(MARKETING_FEE.add(PROJECT_FEE)).div(PERCENTS_DIVIDER));
  45. User storage user = users[msg.sender];
  46. if (user.referrer == address(0) && users[referrer].deposits.length > 0 && referrer != msg.sender) {
  47. user.referrer = referrer;
  48. }
  49. if (user.referrer != address(0)) {
  50. address upline = user.referrer;
  51. for (uint256 i = 0; i < 3; i++) {
  52. if (upline != address(0)) {
  53. uint256 amount = msg.value.mul(REFERRAL_PERCENTS[i]).div(PERCENTS_DIVIDER);
  54. users[upline].bonus = users[upline].bonus.add(amount);
  55. emit RefBonus(upline, msg.sender, i, amount);
  56. upline = users[upline].referrer;
  57. } else break;
  58. }
  59. }
  60. if (user.deposits.length == 0) {
  61. user.checkpoint = block.timestamp;
  62. totalUsers = totalUsers.add(1);
  63. emit Newbie(msg.sender);
  64. }
  65. user.deposits.push(Deposit(msg.value, 0, block.timestamp));
  66. totalInvested = totalInvested.add(msg.value);
  67. totalDeposits = totalDeposits.add(1);
  68. emit NewDeposit(msg.sender, msg.value);
  69. }
  70. function withdraw() public {
  71. User storage user = users[msg.sender];
  72. uint256 userPercentRate = getUserPercentRate(msg.sender);
  73. uint256 totalAmount;
  74. uint256 dividends;
  75. for (uint256 i = 0; i < user.deposits.length; i++) {
  76. if (user.deposits[i].withdrawn < user.deposits[i].amount.mul(2)) {
  77. if (user.deposits[i].start > user.checkpoint) {
  78. dividends = (user.deposits[i].amount.mul(userPercentRate).div(PERCENTS_DIVIDER))
  79. .mul(block.timestamp.sub(user.deposits[i].start))
  80. .div(TIME_STEP);
  81. } else {
  82. dividends = (user.deposits[i].amount.mul(userPercentRate).div(PERCENTS_DIVIDER))
  83. .mul(block.timestamp.sub(user.checkpoint))
  84. .div(TIME_STEP);
  85. }
  86. if (user.deposits[i].withdrawn.add(dividends) > user.deposits[i].amount.mul(2)) {
  87. dividends = (user.deposits[i].amount.mul(2)).sub(user.deposits[i].withdrawn);
  88. }
  89. user.deposits[i].withdrawn = user.deposits[i].withdrawn.add(dividends); /// changing of storage data
  90. totalAmount = totalAmount.add(dividends);
  91. }
  92. }
  93. uint256 referralBonus = getUserReferralBonus(msg.sender);
  94. if (referralBonus > 0) {
  95. totalAmount = totalAmount.add(referralBonus);
  96. user.bonus = 0;
  97. }
  98. require(totalAmount > 0, "User has no dividends");
  99. uint256 contractBalance = address(this).balance;
  100. if (contractBalance < totalAmount) {
  101. totalAmount = contractBalance;
  102. }
  103. user.checkpoint = block.timestamp;
  104. msg.sender.transfer(totalAmount);
  105. totalWithdrawn = totalWithdrawn.add(totalAmount);
  106. emit Withdrawn(msg.sender, totalAmount);
  107. }
  108. function getContractBalance() public view returns (uint256) {
  109. return address(this).balance;
  110. }
  111. function getContractBalanceRate() public view returns (uint256) {
  112. uint256 contractBalance = address(this).balance;
  113. uint256 contractBalancePercent = contractBalance.div(CONTRACT_BALANCE_STEP);
  114. return BASE_PERCENT.add(contractBalancePercent);
  115. }
  116. function getUserPercentRate(address userAddress) public view returns (uint256) {
  117. User storage user = users[userAddress];
  118. uint256 contractBalanceRate = getContractBalanceRate();
  119. if (isActive(userAddress)) {
  120. uint256 timeMultiplier = (now.sub(user.checkpoint)).div(TIME_STEP);
  121. return contractBalanceRate.add(timeMultiplier);
  122. } else {
  123. return contractBalanceRate;
  124. }
  125. }
  126. function getUserDividends(address userAddress) public view returns (uint256) {
  127. User storage user = users[userAddress];
  128. uint256 userPercentRate = getUserPercentRate(userAddress);
  129. uint256 totalDividends;
  130. uint256 dividends;
  131. for (uint256 i = 0; i < user.deposits.length; i++) {
  132. if (user.deposits[i].withdrawn < user.deposits[i].amount.mul(2)) {
  133. if (user.deposits[i].start > user.checkpoint) {
  134. dividends = (user.deposits[i].amount.mul(userPercentRate).div(PERCENTS_DIVIDER))
  135. .mul(block.timestamp.sub(user.deposits[i].start))
  136. .div(TIME_STEP);
  137. } else {
  138. dividends = (user.deposits[i].amount.mul(userPercentRate).div(PERCENTS_DIVIDER))
  139. .mul(block.timestamp.sub(user.checkpoint))
  140. .div(TIME_STEP);
  141. }
  142. if (user.deposits[i].withdrawn.add(dividends) > user.deposits[i].amount.mul(2)) {
  143. dividends = (user.deposits[i].amount.mul(2)).sub(user.deposits[i].withdrawn);
  144. }
  145. totalDividends = totalDividends.add(dividends);
  146. /// no update of withdrawn because that is view function
  147. }
  148. }
  149. return totalDividends;
  150. }
  151. function getUserCheckpoint(address userAddress) public view returns(uint256) {
  152. return users[userAddress].checkpoint;
  153. }
  154. function getUserReferrer(address userAddress) public view returns(address) {
  155. return users[userAddress].referrer;
  156. }
  157. function getUserReferralBonus(address userAddress) public view returns(uint256) {
  158. return users[userAddress].bonus;
  159. }
  160. function getUserAvailable(address userAddress) public view returns(uint256) {
  161. return getUserReferralBonus(userAddress).add(getUserDividends(userAddress));
  162. }
  163. function isActive(address userAddress) public view returns (bool) {
  164. User storage user = users[userAddress];
  165. if (user.deposits.length > 0) {
  166. if (user.deposits[user.deposits.length-1].withdrawn < user.deposits[user.deposits.length-1].amount.mul(2)) {
  167. return true;
  168. }
  169. }
  170. }
  171. function getUserDepositInfo(address userAddress, uint256 index) public view returns(uint256, uint256, uint256) {
  172. User storage user = users[userAddress];
  173. return (user.deposits[index].amount, user.deposits[index].withdrawn, user.deposits[index].start);
  174. }
  175. function getUserAmountOfDeposits(address userAddress) public view returns(uint256) {
  176. return users[userAddress].deposits.length;
  177. }
  178. function getUserTotalDeposits(address userAddress) public view returns(uint256) {
  179. User storage user = users[userAddress];
  180. uint256 amount;
  181. for (uint256 i = 0; i < user.deposits.length; i++) {
  182. amount = amount.add(user.deposits[i].amount);
  183. }
  184. return amount;
  185. }
  186. function getUserTotalWithdrawn(address userAddress) public view returns(uint256) {
  187. User storage user = users[userAddress];
  188. uint256 amount;
  189. for (uint256 i = 0; i < user.deposits.length; i++) {
  190. amount = amount.add(user.deposits[i].withdrawn);
  191. }
  192. return amount;
  193. }
  194. function isContract(address addr) internal view returns (bool) {
  195. uint size;
  196. assembly { size := extcodesize(addr) }
  197. return size > 0;
  198. }
  199. }
  200. library SafeMath {
  201. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  202. uint256 c = a + b;
  203. require(c >= a, "SafeMath: addition overflow");
  204. return c;
  205. }
  206. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  207. require(b <= a, "SafeMath: subtraction overflow");
  208. uint256 c = a - b;
  209. return c;
  210. }
  211. function mul(uint256 a, uint256 b) internal pure returns (uint256) {
  212. if (a == 0) {
  213. return 0;
  214. }
  215. uint256 c = a * b;
  216. require(c / a == b, "SafeMath: multiplication overflow");
  217. return c;
  218. }
  219. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  220. require(b > 0, "SafeMath: division by zero");
  221. uint256 c = a / b;
  222. return c;
  223. }
  224. }
Advertisement
Add Comment
Please, Sign In to add comment