Advertisement
Guest User

Untitled

a guest
Dec 14th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.08 KB | None | 0 0
  1. pragma solidity 0.5.11;
  2.  
  3. import "./SafeMath.sol";
  4. import "./Erc20.sol";
  5.  
  6. contract BucketSale
  7. {
  8. using SafeMath for uint256;
  9.  
  10. uint public HUNDRED_PERC = 100000;
  11.  
  12. struct Buy
  13. {
  14. uint valueEntered;
  15. uint tokensExited;
  16. bool haveWithdrawn;
  17. address referralAddress;
  18. }
  19.  
  20. struct Bucket
  21. {
  22. uint totalValueEntered;
  23. }
  24.  
  25. mapping (uint => Bucket) public buckets;
  26. mapping (uint => mapping (address => Buy)) public buys;
  27. mapping (address => uint) public referredTotal;
  28.  
  29. address public owner;
  30. uint public startOfSale;
  31. uint public endOfSale;
  32. uint public bucketPeriod;
  33. uint public bucketSupply;
  34. Erc20 public tokenOnSale;
  35. Erc20 public tokenSoldFor;
  36.  
  37. constructor (
  38. uint _bucketPeriod,
  39. uint _bucketSupply,
  40. Erc20 _tokeOnSale, // SUGR in our case
  41. Erc20 _tokenSoldFor) // typically DAI
  42. public
  43. {
  44. owner = msg.sender;
  45. bucketPeriod = _bucketPeriod;
  46. bucketSupply = _bucketSupply;
  47. tokenOnSale = _tokeOnSale;
  48. tokenSoldFor = _tokenSoldFor;
  49. }
  50.  
  51. modifier onlyOwner()
  52. {
  53. require(msg.sender == owner, "only owner");
  54. _;
  55. }
  56.  
  57. function timestamp() public view returns (uint256 _now) { return block.timestamp; }
  58.  
  59. function startSale(uint256 _startDateTime)
  60. public
  61. onlyOwner
  62. {
  63. startOfSale = _startDateTime;
  64. }
  65.  
  66. function stopSale(uint _inputEndOfSale)
  67. public
  68. onlyOwner
  69. {
  70. require(_inputEndOfSale < timestamp(), "cannot be in the past");
  71. require(endOfSale == 0 || endOfSale < timestamp(), "cannot extend sale after end date has passed");
  72. endOfSale = _inputEndOfSale;
  73. }
  74.  
  75. event Drained(address indexed _target, uint _amount);
  76. function drain(address _target)
  77. public
  78. onlyOwner
  79. {
  80. uint balance = tokenSoldFor.balanceOf(address(this));
  81. bool transferSuccess = tokenSoldFor.transfer(_target, balance);
  82. require(transferSuccess, "transfer failed");
  83. emit Drained(_target, balance);
  84. }
  85.  
  86. function currentBucket()
  87. public
  88. view
  89. returns (uint)
  90. {
  91. if (endOfSale == 0 || endOfSale > timestamp())
  92. {
  93. return timestamp().sub(startOfSale).div(bucketPeriod);
  94. }
  95. else
  96. {
  97. return endOfSale.sub(startOfSale).div(bucketPeriod);
  98. }
  99. }
  100.  
  101. event Entered(address indexed _buyer, uint256 _bucket, uint _amount);
  102. function enter(address _buyer, uint _amount, address _referralAddress)
  103. public
  104. {
  105. require(_amount > 0, "can't buy nothing");
  106.  
  107. Buy storage buy = buys[currentBucket()][_buyer];
  108. buy.valueEntered = buy.valueEntered.add(_amount);
  109.  
  110. Bucket storage bucket = buckets[currentBucket()];
  111. bucket.totalValueEntered = bucket.totalValueEntered.add(_amount);
  112. bucket.referralAddress = _referralAddress;
  113. referredTotal[_referralAddress] = referredTotal[_referralAddress].add(_amount);
  114.  
  115. bool transferSuccess = tokenSoldFor.transferFrom(_buyer, address(this), _amount);
  116. require(transferSuccess, "transfer failed");
  117.  
  118. emit Entered(_buyer, currentBucket(), _amount);
  119. }
  120.  
  121. event Exited(address indexed _buyer, uint256 _bucket, uint _amount);
  122. function exit(address _buyer, uint _bucketID)
  123. public
  124. {
  125. require(
  126. timestamp() < endOfSale || _bucketID < currentBucket(),
  127. "can only exit from concluded buckets");
  128.  
  129. Buy storage buyToWithdraw = buys[_bucketID][msg.sender];
  130. require(buyToWithdraw.valueEntered > 0, "can't take out if you didn't put in");
  131. require(!buyToWithdraw.haveWithdrawn, "already withdrawn");
  132.  
  133. Bucket storage bucket = buckets[_bucketID];
  134. uint baseAmount = bucketSupply.mul(buyToWithdraw.valueEntered).div(bucket.totalValueEntered);
  135. uint rewardAmount = baseAmount.mul().div(1000000);
  136. uint referralAmount = baseAmount.mul(referrerReferralRewardPerc(buy.referralAddress)).div(HUNDRED_PERC);
  137. buyToWithdraw.haveWithdrawn = true;
  138.  
  139. bool transferSuccess = tokenOnSale.transfer(msg.sender, baseAmount);
  140. require(transferSuccess, "erc20 base transfer failed");
  141.  
  142. bool rewardTransferSuccess = tokenOnSale.transfer(msg.sender, referralAmount);
  143. require(transferSuccess, "erc20 referral reward transfer failed");
  144.  
  145. emit Exited(_buyer, _bucketID, baseAmount);
  146. }
  147.  
  148. function buyerReferralRewardPerc(address _referralAddress)
  149. public
  150. returns(uint)
  151. {
  152. return 1100000;
  153. }
  154.  
  155. //perc is between 0 and 100k, so 3 decimal precision.
  156. function referrerReferralRewardPerc(address _referralAddress)
  157. public
  158. returns(uint)
  159. {
  160. uint daiContributed = referredTotal[_referralAddress].div(1000000000000000000);
  161. uint multiplier = daiContributed + 10000;
  162. uint result = min(HUNDRED_PERC, multiplier);
  163. return result;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement