Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @title FTICrowdsale
- * @dev This is FTICrowdsale contract.
- * In this crowdsale we are providing following extensions:
- * CappedCrowdsale - sets a max boundary for raised funds
- * MintedCrowdsale - set a min goal to be reached and returns funds if it's
- not met
- *
- * After adding multiple features it's good practice to run integration
- tests
- * to ensure that subcontracts works together as intended.
- */
- contract FTICrowdsale is CappedCrowdsale, MintedCrowdsale, ClosedPeriod, Ownable {
- using SafeMath for uint256;
- uint256 public referralMinimum;
- uint8 public additionalTokenRate;
- uint8 public referralPercent;
- uint8 public referralOwnerPercent;
- bool public openingManualyMining = true;
- modifier onlyOpeningManualyMinig() {
- require(openingManualyMining);
- _;
- }
- struct Pay {
- address payer;
- uint256 amount;
- }
- struct ReferalUser {
- uint256 fundsTotal;
- uint32 numReferrals;
- uint256 amountWEI;
- uint32 paysCount;
- mapping (uint32 => Pay) pays;
- mapping (uint32 => address) paysUniq;
- mapping (address => uint256) referral;
- }
- mapping (address => ReferalUser) public referralAddresses;
- uint8 constant maxGlobInvestor = 5;
- struct BonusPeriod {
- uint64 from;
- uint64 to;
- uint256 min_amount;
- uint256 max_amount;
- uint8 bonus;
- uint8 index_global_investor;
- }
- BonusPeriod[] public bonus_periods;
- mapping (uint8 => address[]) public globalInvestor;
- constructor(
- uint256 _openingTime,
- uint256 _closingTime,
- uint256 _openClosePeriod,
- uint256 _endClosePeriod,
- uint256 _rate,
- address _wallet,
- uint256 _cap,
- FTIToken _token,
- uint8 _additionalTokenRate,
- uint8 _referralPercent,
- uint256 _referralMinimum,
- uint8 _referralOwnerPercent,
- uint256 _startWeiAmount
- ) public
- Crowdsale(_rate, _wallet, _token)
- CappedCrowdsale(_cap)
- ClosedPeriod(_openingTime, _closingTime, _openClosePeriod, _endClosePeriod)
- {
- require(_additionalTokenRate > 0);
- require(_referralPercent > 0);
- require(_referralMinimum > 0);
- require(_referralOwnerPercent > 0);
- additionalTokenRate = _additionalTokenRate;
- referralPercent = _referralPercent;
- referralMinimum = _referralMinimum;
- referralOwnerPercent = _referralOwnerPercent;
- weiRaised = _startWeiAmount;
- }
- function manualyAddReferral(address ref, uint256 amount) public onlyOwner() {
- referralAddresses[ref] = ReferalUser(0,0,amount,0);
- }
- function manualyAddReferralPayer(address ref, address _beneficiary, uint256 _weiAmount) public onlyOwner() {
- ReferalUser storage rr = referralAddresses[ref];
- if (rr.amountWEI > 0) {
- uint mintTokens = _weiAmount.mul(rate);
- uint256 ownerToken = mintTokens.mul(referralOwnerPercent).div(100);
- rr.fundsTotal += ownerToken;
- if (rr.referral[_beneficiary] == 0){
- rr.paysUniq[rr.numReferrals] = _beneficiary;
- rr.numReferrals += 1;
- }
- rr.referral[_beneficiary] += _weiAmount;
- rr.pays[rr.paysCount] = Pay(_beneficiary, _weiAmount);
- rr.paysCount += 1;
- }
- }
- function bytesToAddress(bytes source) internal constant returns(address parsedReferer) {
- assembly {
- parsedReferer := mload(add(source,0x14))
- }
- require(parsedReferer != msg.sender);
- return parsedReferer;
- }
- function processReferral(address owner, address _beneficiary, uint256 _weiAmount) internal {
- require(owner != address(0));
- require(_beneficiary != address(0));
- require(_weiAmount != 0);
- ReferalUser storage rr = referralAddresses[owner];
- if (rr.amountWEI > 0) {
- uint mintTokens = _weiAmount.mul(rate);
- uint256 ownerToken = mintTokens.mul(referralOwnerPercent).div(100);
- rr.fundsTotal += ownerToken;
- if (rr.referral[_beneficiary] == 0){
- rr.paysUniq[rr.numReferrals] = _beneficiary;
- rr.numReferrals += 1;
- }
- rr.referral[_beneficiary] += _weiAmount;
- rr.pays[rr.paysCount] = Pay(_beneficiary, _weiAmount);
- rr.paysCount += 1;
- FTIToken(token).mint(owner, ownerToken);
- FTIToken(token).mint(_beneficiary, mintTokens.mul(referralPercent).div(100));
- }
- }
- function addReferral(address _beneficiary, uint256 _weiAmount) internal {
- if (_weiAmount > referralMinimum) {
- ReferalUser storage r = referralAddresses[_beneficiary];
- if (r.amountWEI > 0 ) {
- r.amountWEI += _weiAmount;
- }
- else {
- referralAddresses[_beneficiary] = ReferalUser(0, 0, _weiAmount, 0);
- }
- }
- }
- function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal {
- if (msg.data.length == 20) {
- address ref = bytesToAddress(msg.data);
- processReferral(ref, _beneficiary, _weiAmount);
- }
- addReferral(_beneficiary, _weiAmount);
- uint8 index = indexSuperInvestor(_weiAmount);
- if (index > 0 && globalInvestor[index].length < maxGlobInvestor) {
- bool found = false;
- for (uint8 iter = 0; iter < globalInvestor[index].length; iter++) {
- if (globalInvestor[index][iter] == _beneficiary) {
- found = true;
- }
- }
- if (!found) {
- globalInvestor[index].push(_beneficiary);
- }
- }
- }
- function addBonusPeriod (uint64 from, uint64 to, uint256 min_amount, uint8 bonus, uint256 max_amount, uint8 index_glob_inv) public onlyOwner {
- bonus_periods.push(BonusPeriod(from, to, min_amount, max_amount, bonus, index_glob_inv));
- }
- function referalCount (address addr) public view returns(uint64 len) {
- len = referralAddresses[addr].numReferrals;
- }
- function referalAddrByNum (address ref_owner, uint32 num) public view returns(address addr) {
- addr = referralAddresses[ref_owner].paysUniq[num];
- }
- function referalPayCount (address addr) public view returns(uint64 len) {
- len = referralAddresses[addr].paysCount;
- }
- function referalPayByNum (address ref_owner, uint32 num) public view returns(address addr, uint256 amount) {
- addr = referralAddresses[ref_owner].pays[num].payer;
- amount = referralAddresses[ref_owner].pays[num].amount;
- }
- function getBonusRate (uint256 amount) public constant returns(uint8) {
- for (uint i = 0; i < bonus_periods.length; i++) {
- BonusPeriod storage bonus_period = bonus_periods[i];
- if (bonus_period.from <= now && bonus_period.to > now && bonus_period.min_amount <= amount && bonus_period.max_amount > amount) {
- return bonus_period.bonus;
- }
- }
- return 0;
- }
- function indexSuperInvestor (uint256 amount) internal view returns(uint8) {
- for (uint8 i = 0; i < bonus_periods.length; i++) {
- BonusPeriod storage bonus_period = bonus_periods[i];
- if (bonus_period.from <= now && bonus_period.to > now && bonus_period.min_amount <= amount && bonus_period.max_amount > amount) {
- return bonus_period.index_global_investor;
- }
- }
- return 0;
- }
- function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) {
- uint8 bonusPercent = 100 + getBonusRate(_weiAmount);
- uint256 amountTokens = _weiAmount.mul(rate).mul(bonusPercent).div(100);
- return amountTokens;
- }
- function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal {
- super._processPurchase(_beneficiary, _tokenAmount);
- FTIToken(token).mint(wallet, _tokenAmount.mul(additionalTokenRate).div(100));
- }
- function closeManualyMining() public onlyOwner() {
- openingManualyMining = false;
- }
- function manualyMintTokens(uint256 _weiAmount, address _beneficiary, uint256 mintTokens) public onlyOwner() onlyOpeningManualyMinig() {
- require(_beneficiary != address(0));
- require(_weiAmount != 0);
- require(mintTokens != 0);
- weiRaised = weiRaised.add(_weiAmount);
- _processPurchase(_beneficiary, mintTokens);
- emit TokenPurchase(
- msg.sender,
- _beneficiary,
- _weiAmount,
- mintTokens
- );
- addReferral(_beneficiary, _weiAmount);
- }
- }
Add Comment
Please, Sign In to add comment