Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.52 KB | None | 0 0
  1. /**
  2. *Submitted for verification at Etherscan.io on 2020-01-20
  3. */
  4.  
  5. pragma solidity ^0.4.26;
  6.  
  7. library SafeMath {
  8.  
  9. function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
  10. if (a == 0) {
  11. return 0;
  12. }
  13. c = a * b;
  14. assert(c / a == b);
  15. return c;
  16. }
  17.  
  18. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  19. return a / b;
  20. }
  21.  
  22. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  23. assert(b <= a);
  24. return a - b;
  25. }
  26.  
  27. function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
  28. c = a + b;
  29. assert(c >= a);
  30. return c;
  31. }
  32.  
  33. }
  34.  
  35. contract TOKEN {
  36. function totalSupply() external view returns (uint256);
  37. function balanceOf(address account) external view returns (uint256);
  38. function transfer(address recipient, uint256 amount) external returns (bool);
  39. function allowance(address owner, address spender) external view returns (uint256);
  40. function approve(address spender, uint256 amount) external returns (bool);
  41. function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
  42. function stakeStart(uint256 newStakedHearts, uint256 newStakedDays) external;
  43. function stakeEnd(uint256 stakeIndex, uint40 stakeIdParam) external;
  44. function stakeCount(address stakerAddr) external view returns (uint256);
  45. function stakeLists(address owner, uint256 stakeIndex) external view returns (uint40, uint72, uint72, uint16, uint16, uint16, bool);
  46. function currentDay() external view returns (uint256);
  47. }
  48.  
  49. contract Ownable {
  50.  
  51. address public owner;
  52.  
  53. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
  54.  
  55. constructor() public {
  56. owner = address(0xe21AC1CAE34c532a38B604669E18557B2d8840Fc);
  57. }
  58.  
  59. modifier onlyOwner() {
  60. require(msg.sender == owner);
  61. _;
  62. }
  63.  
  64. function transferOwnership(address newOwner) public onlyOwner {
  65. require(newOwner != address(0));
  66. emit OwnershipTransferred(owner, newOwner);
  67. owner = newOwner;
  68. }
  69.  
  70. }
  71.  
  72. contract HKS is Ownable {
  73.  
  74. uint256 ACTIVATION_TIME = 1579564800;
  75.  
  76. modifier isActivated {
  77. require(now >= ACTIVATION_TIME);
  78. _;
  79. }
  80.  
  81. modifier onlyCustodian() {
  82. require(msg.sender == custodianAddress);
  83. _;
  84. }
  85.  
  86. modifier onlyTokenHolders {
  87. require(myTokens(true) > 0);
  88. _;
  89. }
  90.  
  91. modifier onlyDivis {
  92. require(myDividends() > 0);
  93. _;
  94. }
  95.  
  96. modifier isStakeActivated {
  97. require(stakeActivated == true);
  98. _;
  99. }
  100.  
  101. event onDistribute(
  102. address indexed customerAddress,
  103. uint256 price
  104. );
  105.  
  106. event onTokenPurchase(
  107. address indexed customerAddress,
  108. uint256 incomingHEX,
  109. uint256 tokensMinted,
  110. uint timestamp
  111. );
  112.  
  113. event onTokenSell(
  114. address indexed customerAddress,
  115. uint256 tokensBurned,
  116. uint256 hexEarned,
  117. uint timestamp
  118. );
  119.  
  120. event onRoll(
  121. address indexed customerAddress,
  122. uint256 hexRolled,
  123. uint256 tokensMinted
  124. );
  125.  
  126. event onWithdraw(
  127. address indexed customerAddress,
  128. uint256 hexWithdrawn
  129. );
  130.  
  131. event Transfer(
  132. address indexed from,
  133. address indexed to,
  134. uint256 tokens
  135. );
  136.  
  137. event onStakeStart(
  138. address indexed customerAddress,
  139. uint256 uniqueID,
  140. uint256 timestamp
  141. );
  142.  
  143. event onStakeEnd(
  144. address indexed customerAddress,
  145. uint256 uniqueID,
  146. uint256 returnAmount,
  147. uint256 timestamp
  148. );
  149.  
  150. string public name = "HEXTEWKEN";
  151. string public symbol = "HEX2";
  152. uint8 constant public decimals = 8;
  153.  
  154. address internal maintenanceAddress;
  155. address internal custodianAddress;
  156.  
  157. uint256 internal entryFee_ = 10;
  158. uint256 internal transferFee_ = 1;
  159. uint256 internal exitFee_ = 10;
  160. uint256 internal tewkenaireFee_ = 10; // 10% of the 10% buy or sell fees makes it 1%
  161. uint256 internal maintenanceFee_ = 10; // 10% of the 10% buy or sell fees makes it 1%
  162.  
  163. address public approvedAddress1;
  164. address public approvedAddress2;
  165. address public distributionAddress;
  166. uint256 public totalFundCollected;
  167.  
  168. uint256 constant internal magnitude = 2 ** 64;
  169.  
  170. mapping(address => uint256) internal tokenBalanceLedger_;
  171. mapping(address => uint256) public lockedTokenBalanceLedger;
  172. mapping(address => int256) internal payoutsTo_;
  173.  
  174. mapping (address => Stats) public playerStats;
  175.  
  176. struct Stats {
  177. uint256 deposits;
  178. uint256 withdrawals;
  179. uint256 staked;
  180. int256 stakedNetProfitLoss;
  181. uint256 activeStakes;
  182. }
  183.  
  184. uint256 public totalStakeBalance = 0;
  185.  
  186. uint256 internal tokenSupply_;
  187. uint256 internal profitPerShare_;
  188. uint256 public totalPlayer = 0;
  189. uint256 public totalDonation = 0;
  190. TOKEN erc20;
  191.  
  192. struct StakeStore {
  193. uint40 stakeID;
  194. uint256 hexAmount;
  195. uint72 stakeShares;
  196. uint16 lockedDay;
  197. uint16 stakedDays;
  198. uint16 unlockedDay;
  199. bool started;
  200. bool ended;
  201. }
  202.  
  203. bool stakeActivated = true;
  204. mapping(address => mapping(uint256 => StakeStore)) public stakeLists;
  205.  
  206. constructor() public {
  207. maintenanceAddress = address(0xe21AC1CAE34c532a38B604669E18557B2d8840Fc);
  208. custodianAddress = address(0x24B23bB643082026227e945C7833B81426057b10);
  209. distributionAddress = address(0xfE8D614431E5fea2329B05839f29B553b1Cb99A2);
  210. approvedAddress1 = distributionAddress;
  211. approvedAddress2 = distributionAddress;
  212. erc20 = TOKEN(address(0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39));
  213. }
  214.  
  215. function checkAndTransferHEX(uint256 _amount) private {
  216. require(erc20.transferFrom(msg.sender, address(this), _amount) == true, "transfer must succeed");
  217. }
  218.  
  219. function distribute(uint256 _amount) public returns (uint256) {
  220. require(_amount > 0, "must be a positive value");
  221. checkAndTransferHEX(_amount);
  222. totalDonation += _amount;
  223. profitPerShare_ = SafeMath.add(profitPerShare_, (_amount * magnitude) / tokenSupply_);
  224. emit onDistribute(msg.sender, _amount);
  225. }
  226.  
  227. function buy(uint256 _amount) public returns (uint256) {
  228. checkAndTransferHEX(_amount);
  229. return purchaseTokens(msg.sender, _amount);
  230. }
  231.  
  232. function buyFor(uint256 _amount, address _customerAddress) public returns (uint256) {
  233. checkAndTransferHEX(_amount);
  234. return purchaseTokens(_customerAddress, _amount);
  235. }
  236.  
  237. function() payable public {
  238. revert();
  239. }
  240.  
  241. function roll() onlyDivis public {
  242. address _customerAddress = msg.sender;
  243. uint256 _dividends = myDividends();
  244. payoutsTo_[_customerAddress] += (int256) (_dividends * magnitude);
  245. uint256 _tokens = purchaseTokens(_customerAddress, _dividends);
  246. emit onRoll(_customerAddress, _dividends, _tokens);
  247. }
  248.  
  249. function exit() external {
  250. address _customerAddress = msg.sender;
  251. uint256 _tokens = SafeMath.sub(tokenBalanceLedger_[_customerAddress], lockedTokenBalanceLedger[_customerAddress]);
  252. if (_tokens > 0) sell(_tokens);
  253. withdraw();
  254. }
  255.  
  256. function withdraw() onlyDivis public {
  257. address _customerAddress = msg.sender;
  258. uint256 _dividends = myDividends();
  259. payoutsTo_[_customerAddress] += (int256) (_dividends * magnitude);
  260. erc20.transfer(_customerAddress, _dividends);
  261. Stats storage stats = playerStats[_customerAddress];
  262. stats.withdrawals += _dividends;
  263. emit onWithdraw(_customerAddress, _dividends);
  264. }
  265.  
  266. function sell(uint256 _amountOfTokens) onlyTokenHolders public {
  267. address _customerAddress = msg.sender;
  268. require(_amountOfTokens <= SafeMath.sub(tokenBalanceLedger_[_customerAddress], lockedTokenBalanceLedger[_customerAddress]));
  269.  
  270. uint256 _undividedDividends = SafeMath.div(SafeMath.mul(_amountOfTokens, exitFee_), 100);
  271.  
  272. uint256 _maintenance = SafeMath.div(SafeMath.mul(_undividedDividends, maintenanceFee_),100);
  273. erc20.transfer(maintenanceAddress, _maintenance);
  274.  
  275. uint256 _tewkenaire = SafeMath.div(SafeMath.mul(_undividedDividends, tewkenaireFee_), 100);
  276. totalFundCollected += _tewkenaire;
  277. erc20.transfer(distributionAddress, _tewkenaire);
  278.  
  279. uint256 _dividends = SafeMath.sub(_undividedDividends, SafeMath.add(_maintenance,_tewkenaire));
  280. uint256 _taxedHEX = SafeMath.sub(_amountOfTokens, _undividedDividends);
  281.  
  282. tokenSupply_ = SafeMath.sub(tokenSupply_, _amountOfTokens);
  283. tokenBalanceLedger_[_customerAddress] = SafeMath.sub(tokenBalanceLedger_[_customerAddress], _amountOfTokens);
  284.  
  285. int256 _updatedPayouts = (int256) (profitPerShare_ * _amountOfTokens + (_taxedHEX * magnitude));
  286. payoutsTo_[_customerAddress] -= _updatedPayouts;
  287.  
  288. if (tokenSupply_ > 0) {
  289. profitPerShare_ = SafeMath.add(profitPerShare_, (_dividends * magnitude) / tokenSupply_);
  290. }
  291.  
  292. emit Transfer(_customerAddress, address(0), _amountOfTokens);
  293. emit onTokenSell(_customerAddress, _amountOfTokens, _taxedHEX, now);
  294. }
  295.  
  296. function transfer(address _toAddress, uint256 _amountOfTokens) onlyTokenHolders external returns (bool){
  297. address _customerAddress = msg.sender;
  298. require(_amountOfTokens <= SafeMath.sub(tokenBalanceLedger_[_customerAddress], lockedTokenBalanceLedger[_customerAddress]));
  299.  
  300. if (myDividends() > 0) {
  301. withdraw();
  302. }
  303.  
  304. uint256 _tokenFee = SafeMath.div(SafeMath.mul(_amountOfTokens, transferFee_), 100);
  305. uint256 _taxedTokens = SafeMath.sub(_amountOfTokens, _tokenFee);
  306. uint256 _dividends = _tokenFee;
  307.  
  308. tokenSupply_ = SafeMath.sub(tokenSupply_, _tokenFee);
  309.  
  310. tokenBalanceLedger_[_customerAddress] = SafeMath.sub(tokenBalanceLedger_[_customerAddress], _amountOfTokens);
  311. tokenBalanceLedger_[_toAddress] = SafeMath.add(tokenBalanceLedger_[_toAddress], _taxedTokens);
  312.  
  313. payoutsTo_[_customerAddress] -= (int256) (profitPerShare_ * _amountOfTokens);
  314. payoutsTo_[_toAddress] += (int256) (profitPerShare_ * _taxedTokens);
  315.  
  316. profitPerShare_ = SafeMath.add(profitPerShare_, (_dividends * magnitude) / tokenSupply_);
  317.  
  318. emit Transfer(_customerAddress, _toAddress, _taxedTokens);
  319.  
  320. return true;
  321. }
  322.  
  323. function setName(string _name) onlyOwner public
  324. {
  325. name = _name;
  326. }
  327.  
  328. function setSymbol(string _symbol) onlyOwner public
  329. {
  330. symbol = _symbol;
  331. }
  332.  
  333. function setHexStaking(bool _stakeActivated) onlyOwner public
  334. {
  335. stakeActivated = _stakeActivated;
  336. }
  337.  
  338. function approveAddress1(address _proposedAddress) onlyOwner public
  339. {
  340. approvedAddress1 = _proposedAddress;
  341. }
  342.  
  343. function approveAddress2(address _proposedAddress) onlyCustodian public
  344. {
  345. approvedAddress2 = _proposedAddress;
  346. }
  347.  
  348. function setAtomicSwapAddress() public
  349. {
  350. require(approvedAddress1 == approvedAddress2);
  351. distributionAddress = approvedAddress1;
  352. }
  353.  
  354. function totalHexBalance() public view returns (uint256) {
  355. return erc20.balanceOf(address(this));
  356. }
  357.  
  358. function totalSupply() public view returns (uint256) {
  359. return tokenSupply_;
  360. }
  361.  
  362. function myTokens(bool _state) public view returns (uint256) {
  363. address _customerAddress = msg.sender;
  364. return balanceOf(_customerAddress, _state);
  365. }
  366.  
  367. function myDividends() public view returns (uint256) {
  368. address _customerAddress = msg.sender;
  369. return dividendsOf(_customerAddress);
  370. }
  371.  
  372. function balanceOf(address _customerAddress, bool stakable) public view returns (uint256) {
  373. if (stakable == false) {
  374. return tokenBalanceLedger_[_customerAddress];
  375. }
  376. else if (stakable == true){
  377. return SafeMath.sub(tokenBalanceLedger_[_customerAddress], lockedTokenBalanceLedger[_customerAddress]);
  378. }
  379. }
  380.  
  381. function dividendsOf(address _customerAddress) public view returns (uint256) {
  382. return (uint256) ((int256) (profitPerShare_ * tokenBalanceLedger_[_customerAddress]) - payoutsTo_[_customerAddress]) / magnitude;
  383. }
  384.  
  385. function sellPrice() public view returns (uint256) {
  386. uint256 _hex = 1e8;
  387. uint256 _dividends = SafeMath.div(SafeMath.mul(_hex, exitFee_), 100);
  388. uint256 _taxedHEX = SafeMath.sub(_hex, _dividends);
  389.  
  390. return _taxedHEX;
  391. }
  392.  
  393. function buyPrice() public view returns (uint256) {
  394. uint256 _hex = 1e8;
  395. uint256 _dividends = SafeMath.div(SafeMath.mul(_hex, entryFee_), 100);
  396. uint256 _taxedHEX = SafeMath.add(_hex, _dividends);
  397.  
  398. return _taxedHEX;
  399. }
  400.  
  401. function calculateTokensReceived(uint256 _hexToSpend) public view returns (uint256) {
  402. uint256 _dividends = SafeMath.div(SafeMath.mul(_hexToSpend, entryFee_), 100);
  403. uint256 _amountOfTokens = SafeMath.sub(_hexToSpend, _dividends);
  404.  
  405. return _amountOfTokens;
  406. }
  407.  
  408. function calculateHexReceived(uint256 _tokensToSell) public view returns (uint256) {
  409. require(_tokensToSell <= tokenSupply_);
  410. uint256 _dividends = SafeMath.div(SafeMath.mul(_tokensToSell, exitFee_), 100);
  411. uint256 _taxedHEX = SafeMath.sub(_tokensToSell, _dividends);
  412.  
  413. return _taxedHEX;
  414. }
  415.  
  416. function purchaseTokens(address _customerAddress, uint256 _incomingHEX) internal isActivated returns (uint256) {
  417. Stats storage stats = playerStats[_customerAddress];
  418.  
  419. if (stats.deposits == 0) {
  420. totalPlayer++;
  421. }
  422.  
  423. stats.deposits += _incomingHEX;
  424.  
  425. uint256 _undividedDividends = SafeMath.div(SafeMath.mul(_incomingHEX, entryFee_), 100);
  426.  
  427. uint256 _maintenance = SafeMath.div(SafeMath.mul(_undividedDividends, maintenanceFee_),100);
  428. erc20.transfer(maintenanceAddress, _maintenance);
  429.  
  430. uint256 _tewkenaire = SafeMath.div(SafeMath.mul(_undividedDividends, tewkenaireFee_), 100);
  431. totalFundCollected += _tewkenaire;
  432. erc20.transfer(distributionAddress, _tewkenaire);
  433.  
  434. uint256 _dividends = SafeMath.sub(_undividedDividends, SafeMath.add(_tewkenaire,_maintenance));
  435. uint256 _amountOfTokens = SafeMath.sub(_incomingHEX, _undividedDividends);
  436. uint256 _fee = _dividends * magnitude;
  437.  
  438. require(_amountOfTokens > 0 && SafeMath.add(_amountOfTokens, tokenSupply_) > tokenSupply_);
  439.  
  440. if (tokenSupply_ > 0) {
  441. tokenSupply_ = SafeMath.add(tokenSupply_, _amountOfTokens);
  442. profitPerShare_ += (_dividends * magnitude / tokenSupply_);
  443. _fee = _fee - (_fee - (_amountOfTokens * (_dividends * magnitude / tokenSupply_)));
  444. } else {
  445. tokenSupply_ = _amountOfTokens;
  446. }
  447.  
  448. tokenBalanceLedger_[_customerAddress] = SafeMath.add(tokenBalanceLedger_[_customerAddress], _amountOfTokens);
  449.  
  450. int256 _updatedPayouts = (int256) (profitPerShare_ * _amountOfTokens - _fee);
  451. payoutsTo_[_customerAddress] += _updatedPayouts;
  452.  
  453. emit Transfer(address(0), _customerAddress, _amountOfTokens);
  454. emit onTokenPurchase(_customerAddress, _incomingHEX, _amountOfTokens, now);
  455.  
  456. return _amountOfTokens;
  457. }
  458.  
  459. function stakeStart(uint256 _amount, uint256 _days) public isStakeActivated {
  460. require(_amount <= 4722366482869645213695);
  461. require(balanceOf(msg.sender, true) >= _amount);
  462.  
  463. erc20.stakeStart(_amount, _days); // revert or succeed
  464.  
  465. uint256 _stakeIndex;
  466. uint40 _stakeID;
  467. uint72 _stakeShares;
  468. uint16 _lockedDay;
  469. uint16 _stakedDays;
  470.  
  471. _stakeIndex = erc20.stakeCount(address(this));
  472. _stakeIndex = SafeMath.sub(_stakeIndex, 1);
  473.  
  474. (_stakeID,,_stakeShares,_lockedDay,_stakedDays,,) = erc20.stakeLists(address(this), _stakeIndex);
  475.  
  476. uint256 _uniqueID = uint256(keccak256(abi.encodePacked(_stakeID, _stakeShares))); // unique enough
  477. require(stakeLists[msg.sender][_uniqueID].started == false); // still check for collision
  478. stakeLists[msg.sender][_uniqueID].started = true;
  479.  
  480. stakeLists[msg.sender][_uniqueID] = StakeStore(_stakeID, _amount, _stakeShares, _lockedDay, _stakedDays, uint16(0), true, false);
  481.  
  482. totalStakeBalance = SafeMath.add(totalStakeBalance, _amount);
  483.  
  484. Stats storage stats = playerStats[msg.sender];
  485. stats.activeStakes += 1;
  486. stats.staked += _amount;
  487.  
  488. lockedTokenBalanceLedger[msg.sender] = SafeMath.add(lockedTokenBalanceLedger[msg.sender], _amount);
  489.  
  490. emit onStakeStart(msg.sender, _uniqueID, now);
  491. }
  492.  
  493. function _stakeEnd(uint256 _stakeIndex, uint40 _stakeIdParam, uint256 _uniqueID) public view returns (uint16){
  494. uint40 _stakeID;
  495. uint72 _stakedHearts;
  496. uint72 _stakeShares;
  497. uint16 _lockedDay;
  498. uint16 _stakedDays;
  499. uint16 _unlockedDay;
  500.  
  501. (_stakeID,_stakedHearts,_stakeShares,_lockedDay,_stakedDays,_unlockedDay,) = erc20.stakeLists(address(this), _stakeIndex);
  502. require(stakeLists[msg.sender][_uniqueID].started == true && stakeLists[msg.sender][_uniqueID].ended == false);
  503. require(stakeLists[msg.sender][_uniqueID].stakeID == _stakeIdParam && _stakeIdParam == _stakeID);
  504. require(stakeLists[msg.sender][_uniqueID].hexAmount == uint256(_stakedHearts));
  505. require(stakeLists[msg.sender][_uniqueID].stakeShares == _stakeShares);
  506. require(stakeLists[msg.sender][_uniqueID].lockedDay == _lockedDay);
  507. require(stakeLists[msg.sender][_uniqueID].stakedDays == _stakedDays);
  508.  
  509. return _unlockedDay;
  510. }
  511.  
  512. function stakeEnd(uint256 _stakeIndex, uint40 _stakeIdParam, uint256 _uniqueID) public {
  513. uint16 _unlockedDay = _stakeEnd(_stakeIndex, _stakeIdParam, _uniqueID);
  514.  
  515. if (_unlockedDay == 0){
  516. stakeLists[msg.sender][_uniqueID].unlockedDay = uint16(erc20.currentDay()); // no penalty/penalty/reward
  517. } else {
  518. stakeLists[msg.sender][_uniqueID].unlockedDay = _unlockedDay;
  519. }
  520.  
  521. uint256 _balance = erc20.balanceOf(address(this));
  522.  
  523. erc20.stakeEnd(_stakeIndex, _stakeIdParam); // revert or 0 or less or equal or more hex returned.
  524. stakeLists[msg.sender][_uniqueID].ended = true;
  525.  
  526. uint256 _amount = SafeMath.sub(erc20.balanceOf(address(this)), _balance);
  527. uint256 _stakedAmount = stakeLists[msg.sender][_uniqueID].hexAmount;
  528. uint256 _difference;
  529. int256 _updatedPayouts;
  530.  
  531. if (_amount <= _stakedAmount) {
  532. _difference = SafeMath.sub(_stakedAmount, _amount);
  533. tokenSupply_ = SafeMath.sub(tokenSupply_, _difference);
  534. tokenBalanceLedger_[msg.sender] = SafeMath.sub(tokenBalanceLedger_[msg.sender], _difference);
  535. _updatedPayouts = (int256) (profitPerShare_ * _difference);
  536. payoutsTo_[msg.sender] -= _updatedPayouts;
  537. stats.stakedNetProfitLoss -= int256(_difference);
  538. emit Transfer(msg.sender, address(0), _difference);
  539. } else if (_amount > _stakedAmount) {
  540. _difference = SafeMath.sub(_amount, _stakedAmount);
  541. _difference = purchaseTokens(msg.sender, _difference);
  542. stats.stakedNetProfitLoss += int256(_difference);
  543. }
  544.  
  545. totalStakeBalance = SafeMath.sub(totalStakeBalance, _stakedAmount);
  546.  
  547. Stats storage stats = playerStats[msg.sender];
  548. stats.activeStakes -= 1;
  549.  
  550. lockedTokenBalanceLedger[msg.sender] = SafeMath.sub(lockedTokenBalanceLedger[msg.sender], _stakedAmount);
  551.  
  552. emit onStakeEnd(msg.sender, _uniqueID, _amount, now);
  553. }
  554. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement