Guest User

Untitled

a guest
Jun 23rd, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.79 KB | None | 0 0
  1. /**
  2. * @title FTICrowdsale
  3. * @dev This is FTICrowdsale contract.
  4. * In this crowdsale we are providing following extensions:
  5. * CappedCrowdsale - sets a max boundary for raised funds
  6. * MintedCrowdsale - set a min goal to be reached and returns funds if it's
  7. not met
  8. *
  9. * After adding multiple features it's good practice to run integration
  10. tests
  11. * to ensure that subcontracts works together as intended.
  12. */
  13. contract FTICrowdsale is CappedCrowdsale, MintedCrowdsale, ClosedPeriod, Ownable {
  14. using SafeMath for uint256;
  15. uint256 public referralMinimum;
  16. uint8 public additionalTokenRate;
  17. uint8 public referralPercent;
  18. uint8 public referralOwnerPercent;
  19. bool public openingManualyMining = true;
  20.  
  21. modifier onlyOpeningManualyMinig() {
  22. require(openingManualyMining);
  23. _;
  24. }
  25.  
  26. struct Pay {
  27. address payer;
  28. uint256 amount;
  29. }
  30.  
  31. struct ReferalUser {
  32. uint256 fundsTotal;
  33. uint32 numReferrals;
  34. uint256 amountWEI;
  35. uint32 paysCount;
  36. mapping (uint32 => Pay) pays;
  37. mapping (uint32 => address) paysUniq;
  38. mapping (address => uint256) referral;
  39. }
  40. mapping (address => ReferalUser) public referralAddresses;
  41.  
  42. uint8 constant maxGlobInvestor = 5;
  43. struct BonusPeriod {
  44. uint64 from;
  45. uint64 to;
  46. uint256 min_amount;
  47. uint256 max_amount;
  48. uint8 bonus;
  49. uint8 index_global_investor;
  50. }
  51. BonusPeriod[] public bonus_periods;
  52.  
  53. mapping (uint8 => address[]) public globalInvestor;
  54.  
  55. constructor(
  56. uint256 _openingTime,
  57. uint256 _closingTime,
  58. uint256 _openClosePeriod,
  59. uint256 _endClosePeriod,
  60. uint256 _rate,
  61. address _wallet,
  62. uint256 _cap,
  63. FTIToken _token,
  64. uint8 _additionalTokenRate,
  65. uint8 _referralPercent,
  66. uint256 _referralMinimum,
  67. uint8 _referralOwnerPercent,
  68. uint256 _startWeiAmount
  69. ) public
  70. Crowdsale(_rate, _wallet, _token)
  71. CappedCrowdsale(_cap)
  72. ClosedPeriod(_openingTime, _closingTime, _openClosePeriod, _endClosePeriod)
  73. {
  74. require(_additionalTokenRate > 0);
  75. require(_referralPercent > 0);
  76. require(_referralMinimum > 0);
  77. require(_referralOwnerPercent > 0);
  78. additionalTokenRate = _additionalTokenRate;
  79. referralPercent = _referralPercent;
  80. referralMinimum = _referralMinimum;
  81. referralOwnerPercent = _referralOwnerPercent;
  82. weiRaised = _startWeiAmount;
  83. }
  84.  
  85. function manualyAddReferral(address ref, uint256 amount) public onlyOwner() {
  86. referralAddresses[ref] = ReferalUser(0,0,amount,0);
  87. }
  88.  
  89. function manualyAddReferralPayer(address ref, address _beneficiary, uint256 _weiAmount) public onlyOwner() {
  90. ReferalUser storage rr = referralAddresses[ref];
  91. if (rr.amountWEI > 0) {
  92. uint mintTokens = _weiAmount.mul(rate);
  93. uint256 ownerToken = mintTokens.mul(referralOwnerPercent).div(100);
  94. rr.fundsTotal += ownerToken;
  95. if (rr.referral[_beneficiary] == 0){
  96. rr.paysUniq[rr.numReferrals] = _beneficiary;
  97. rr.numReferrals += 1;
  98. }
  99. rr.referral[_beneficiary] += _weiAmount;
  100. rr.pays[rr.paysCount] = Pay(_beneficiary, _weiAmount);
  101. rr.paysCount += 1;
  102. }
  103. }
  104.  
  105. function bytesToAddress(bytes source) internal constant returns(address parsedReferer) {
  106. assembly {
  107. parsedReferer := mload(add(source,0x14))
  108. }
  109. require(parsedReferer != msg.sender);
  110. return parsedReferer;
  111. }
  112.  
  113. function processReferral(address owner, address _beneficiary, uint256 _weiAmount) internal {
  114. require(owner != address(0));
  115. require(_beneficiary != address(0));
  116. require(_weiAmount != 0);
  117. ReferalUser storage rr = referralAddresses[owner];
  118. if (rr.amountWEI > 0) {
  119. uint mintTokens = _weiAmount.mul(rate);
  120. uint256 ownerToken = mintTokens.mul(referralOwnerPercent).div(100);
  121. rr.fundsTotal += ownerToken;
  122. if (rr.referral[_beneficiary] == 0){
  123. rr.paysUniq[rr.numReferrals] = _beneficiary;
  124. rr.numReferrals += 1;
  125. }
  126. rr.referral[_beneficiary] += _weiAmount;
  127. rr.pays[rr.paysCount] = Pay(_beneficiary, _weiAmount);
  128. rr.paysCount += 1;
  129. FTIToken(token).mint(owner, ownerToken);
  130. FTIToken(token).mint(_beneficiary, mintTokens.mul(referralPercent).div(100));
  131. }
  132. }
  133.  
  134. function addReferral(address _beneficiary, uint256 _weiAmount) internal {
  135. if (_weiAmount > referralMinimum) {
  136. ReferalUser storage r = referralAddresses[_beneficiary];
  137. if (r.amountWEI > 0 ) {
  138. r.amountWEI += _weiAmount;
  139. }
  140. else {
  141. referralAddresses[_beneficiary] = ReferalUser(0, 0, _weiAmount, 0);
  142. }
  143. }
  144. }
  145.  
  146. function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal {
  147. if (msg.data.length == 20) {
  148. address ref = bytesToAddress(msg.data);
  149. processReferral(ref, _beneficiary, _weiAmount);
  150. }
  151.  
  152. addReferral(_beneficiary, _weiAmount);
  153.  
  154. uint8 index = indexSuperInvestor(_weiAmount);
  155. if (index > 0 && globalInvestor[index].length < maxGlobInvestor) {
  156. bool found = false;
  157. for (uint8 iter = 0; iter < globalInvestor[index].length; iter++) {
  158. if (globalInvestor[index][iter] == _beneficiary) {
  159. found = true;
  160. }
  161. }
  162. if (!found) {
  163. globalInvestor[index].push(_beneficiary);
  164. }
  165. }
  166. }
  167.  
  168. function addBonusPeriod (uint64 from, uint64 to, uint256 min_amount, uint8 bonus, uint256 max_amount, uint8 index_glob_inv) public onlyOwner {
  169. bonus_periods.push(BonusPeriod(from, to, min_amount, max_amount, bonus, index_glob_inv));
  170. }
  171.  
  172.  
  173. function referalCount (address addr) public view returns(uint64 len) {
  174. len = referralAddresses[addr].numReferrals;
  175. }
  176.  
  177. function referalAddrByNum (address ref_owner, uint32 num) public view returns(address addr) {
  178. addr = referralAddresses[ref_owner].paysUniq[num];
  179. }
  180.  
  181. function referalPayCount (address addr) public view returns(uint64 len) {
  182. len = referralAddresses[addr].paysCount;
  183. }
  184.  
  185. function referalPayByNum (address ref_owner, uint32 num) public view returns(address addr, uint256 amount) {
  186. addr = referralAddresses[ref_owner].pays[num].payer;
  187. amount = referralAddresses[ref_owner].pays[num].amount;
  188. }
  189.  
  190. function getBonusRate (uint256 amount) public constant returns(uint8) {
  191. for (uint i = 0; i < bonus_periods.length; i++) {
  192. BonusPeriod storage bonus_period = bonus_periods[i];
  193. if (bonus_period.from <= now && bonus_period.to > now && bonus_period.min_amount <= amount && bonus_period.max_amount > amount) {
  194. return bonus_period.bonus;
  195. }
  196. }
  197. return 0;
  198. }
  199.  
  200. function indexSuperInvestor (uint256 amount) internal view returns(uint8) {
  201. for (uint8 i = 0; i < bonus_periods.length; i++) {
  202. BonusPeriod storage bonus_period = bonus_periods[i];
  203. if (bonus_period.from <= now && bonus_period.to > now && bonus_period.min_amount <= amount && bonus_period.max_amount > amount) {
  204. return bonus_period.index_global_investor;
  205. }
  206. }
  207. return 0;
  208. }
  209.  
  210. function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) {
  211. uint8 bonusPercent = 100 + getBonusRate(_weiAmount);
  212. uint256 amountTokens = _weiAmount.mul(rate).mul(bonusPercent).div(100);
  213. return amountTokens;
  214. }
  215.  
  216. function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal {
  217. super._processPurchase(_beneficiary, _tokenAmount);
  218. FTIToken(token).mint(wallet, _tokenAmount.mul(additionalTokenRate).div(100));
  219. }
  220.  
  221. function closeManualyMining() public onlyOwner() {
  222. openingManualyMining = false;
  223. }
  224.  
  225. function manualyMintTokens(uint256 _weiAmount, address _beneficiary, uint256 mintTokens) public onlyOwner() onlyOpeningManualyMinig() {
  226. require(_beneficiary != address(0));
  227. require(_weiAmount != 0);
  228. require(mintTokens != 0);
  229. weiRaised = weiRaised.add(_weiAmount);
  230. _processPurchase(_beneficiary, mintTokens);
  231. emit TokenPurchase(
  232. msg.sender,
  233. _beneficiary,
  234. _weiAmount,
  235. mintTokens
  236. );
  237. addReferral(_beneficiary, _weiAmount);
  238. }
  239.  
  240.  
  241. }
Add Comment
Please, Sign In to add comment