0

I'm a newbie trying to make a crowdsale contract in Ropsten (deployed a token contract very well before) but i meet some problems :

  • I can't send ether to crowdsale contract, returning a fail status and "cancelled" (Here's an exemple 0xc0f742937d935200f8ea22f430a942c2291f3154c733025dcad88f2b0c7042b0 )

  • When i compiled in Remix i had

Fallback function of contract TokenCrowdsale requires too much gas (infinite)

and

Gas requirement of function TokenCrowdsale.Buytokens() high: infinite

(and for all other TokenCrowdsale functions).

Because of this "infinite gas cost" i can't interact with deployed crowdsale...

  • I use metamask

  • Crowdsale code :

    pragma solidity ^0.4.20;
    
          library SafeMath {
     function mul(uint256 a, uint256 b) internal pure returns (uint256) {
       if (a == 0) {
         return 0;
       }
       uint256 c = a * b;
       assert(c / a == b);
       return c;
     }
    
     function div(uint256 a, uint256 b) internal pure returns (uint256) {
       // assert(b > 0); // Solidity automatically throws when dividing by 0
       uint256 c = a / b;
       // assert(a == b * c + a % b); // There is no case in which this           doesn't hold
       return c;
     }
    
     function sub(uint256 a, uint256 b) internal pure returns (uint256) {
       assert(b <= a);
       return a - b;
     }
    
     function add(uint256 a, uint256 b) internal pure returns (uint256) {
       uint256 c = a + b;
       assert(c >= a);
       return c;
     }
    }
    
    contract Ownable {
     address public owner;
    
    
     event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    
     function Ownable() public {
       owner = msg.sender;
     }
    
    
     modifier onlyOwner() {
       require(msg.sender == owner);
       _;
     }
    
    
     function transferOwnership(address newOwner) public onlyOwner {
       require(newOwner != address(0));
       OwnershipTransferred(owner, newOwner);
       owner = newOwner;
     }
    
    }
    
    contract PausableToken is Ownable {
       function balanceOf(address who) public constant returns (uint256);
       function transfer(address to, uint256 value) public returns (bool);
       function increaseFrozen(address _owner,uint256 _incrementalAmount) public returns (bool);
       function burn(uint256 _value) public;
    }
    
    contract TokenCrowdsale is Ownable {
       using SafeMath for uint256;
       PausableToken  public tokenReward;                         // address of the token used as reward
    
       // deployment variables for static supply sale
       uint256 public initialSupply;
       uint256 public tokensRemaining;
       uint256 public decimals;
    
       // multi-sig addresses and price variable
       address public beneficiaryWallet;                           //        beneficiaryMultiSig (founder group) or wallet account
       uint256 public tokensPerEthPrice;                           // set initial value floating priceVar 1,000 tokens per Eth
    
       // uint256 values for min,max,caps,tracking
       uint256 public amountRaisedInWei;
       uint256 public fundingMinCapInWei;
    
       // pricing veriable
       uint256 public p1_duration;
       uint256 public p2_start;
    
       // loop control, ICO startup and limiters
       uint256 public fundingStartTime;                           // crowdsale start time#
       uint256 public fundingEndTime;                             // crowdsale end time#
       bool    public isCrowdSaleClosed               = false;     // crowdsale completion boolean
       bool    public areFundsReleasedToBeneficiary   = false;     // boolean for founder to receive Eth or not
       bool    public isCrowdSaleSetup                = false;     // boolean for crowdsale setup
    
        event Buy(address indexed _sender, uint256 _eth, uint256 _LOL);
        event Refund(address indexed _refunder, uint256 _value);
        event Burn(address _from, uint256 _value);
        mapping(address => uint256) fundValue;
    
    
        // convert tokens to decimals
        function toPony(uint256 amount) public constant returns (uint256) {
            return amount.mul(10**decimals);
        }
    
        // convert tokens to whole
        function toHorse(uint256 amount) public constant returns (uint256) {
            return amount.div(10**decimals);
        }
    
        // setup the CrowdSale parameters
        function setupCrowdsale(uint256 _fundingStartTime) external onlyOwner {
            if ((!(isCrowdSaleSetup))
                && (!(beneficiaryWallet > 0))){
                // init addresses
                tokenReward                             =                 PausableToken(0x39B2F057CACdd24663c60bDfD16A609e928D61A3);
                beneficiaryWallet                       = 0x63695289007Ea8Ab78106adc541a0CbF5865c816;
                tokensPerEthPrice                       = 1000;
    
                // funding targets
                fundingMinCapInWei                      = 1 ether;                                          //1 Eth (min cap, very low we know) - crowdsale is considered success after this value
    
                // update values
                decimals                                = 18;
                amountRaisedInWei                       = 0;
                initialSupply                           = toPony(1500000);                                  //   1,5 million * 18 decimal for 2 million tokens
                tokensRemaining                         = initialSupply;
    
                fundingStartTime                        = _fundingStartTime;
                p1_duration                             = 3 days;
                p2_start                                = fundingStartTime +         p1_duration;
    
                fundingEndTime                          = p2_start + 12 days;
    
                // configure crowdsale
                isCrowdSaleSetup                        = true;
                isCrowdSaleClosed                       = false;
            }
        }
    
        function setBonusPrice() public constant returns (uint256 bonus) {
            require(isCrowdSaleSetup);
            require(fundingStartTime + p1_duration <= p2_start );
            if (now >= fundingStartTime && now <= fundingStartTime + p1_duration) { // Phase-1 UltraBonus  +100% = 2,000 TOK  = 1 ETH
                bonus = 1000;
            } else if (now > p2_start && now <= p2_start + 1 days ) { // Phase-2 day-1 MidBonus +50% = 1,500 TOK = 1 ETH
                bonus = 500;
            } else if (now > p2_start + 1 days && now <= p2_start + 3 days - 1 days) { // Phase-2 Bonus +20% = 1,200 TOK = 1 ETH
                bonus = 200;
            } else if (now > p2_start + 3 days && now <= p2_start + 6 days ) { // Phase-2 Bonus +10% = 1,100 TOK = 1 ETH
                bonus = 100;
            } else if (now > p2_start + 6 days && now <= fundingEndTime ) { // Phase-2 week-3& week-4 Bonus +0% = 1,000 TOK = 1 ETH
                bonus = 0;
            } else {
                revert();
            }
        }
    
        function updateDuration(uint256 _newP1Duration, uint256 _newP2Start)         external onlyOwner{ // function to update the duration of phase-1 and adjust the         start time of phase-2
            require( isCrowdSaleSetup
                && !(p1_duration == _newP1Duration)
                && !(p2_start == _newP2Start)
                && (now < fundingStartTime + p1_duration) 
                && (now < fundingStartTime + _newP1Duration)
                && (fundingStartTime + _newP1Duration < _newP2Start));
            p1_duration = _newP1Duration;
            p2_start = _newP2Start;
            fundingEndTime = p2_start + 12 days;
        }
    
        // default payable function when sending ether to this contract
        function () external payable {
            require(msg.data.length == 0);
            Buytokens();
        }
    
        function Buytokens() public payable {
            // conditions (length, crowdsale setup, zero check, exceed         funding contrib check, contract valid check, within funding block range check,         balance overflow check etc)
            require(!(msg.value == 0)
            && (isCrowdSaleSetup)
            && (now >= fundingStartTime)
            && (now <= fundingEndTime)
            && (tokensRemaining > 0));
    
            uint256 rewardTransferAmount        = 0;
            uint256 rewardBaseTransferAmount    = 0;
            uint256 rewardBonusTransferAmount   = 0;
            uint256 contributionInWei           = msg.value;
            uint256 refundInWei                 = 0;
    
            rewardBonusTransferAmount       = setBonusPrice();
            rewardBaseTransferAmount        =         (msg.value.mul(tokensPerEthPrice)); // Since both ether and token have 18 decimals, No need of conversion
            rewardBonusTransferAmount       = (msg.value.mul(rewardBonusTransferAmount)); // Since both ether and token have 18 decimals, No need of conversion
            rewardTransferAmount            =         rewardBaseTransferAmount.add(rewardBonusTransferAmount);
    
            if (rewardTransferAmount > tokensRemaining) {
                uint256 partialPercentage;
                partialPercentage = tokensRemaining.mul(10**18).div(rewardTransferAmount);
                contributionInWei = contributionInWei.mul(partialPercentage).div(10**18);
                rewardBonusTransferAmount = rewardBonusTransferAmount.mul(partialPercentage).div(10**18);
                rewardTransferAmount = tokensRemaining;
                refundInWei = msg.value.sub(contributionInWei);
            }
    
            amountRaisedInWei               = amountRaisedInWei.add(contributionInWei);
            tokensRemaining                 = tokensRemaining.sub(rewardTransferAmount);  // will cause throw if attempt to purchase over the token limit in one tx or at all once limit reached
            fundValue[msg.sender]           = fundValue[msg.sender].add(contributionInWei);
            assert(tokenReward.increaseFrozen(msg.sender, rewardBonusTransferAmount));
            tokenReward.transfer(msg.sender, rewardTransferAmount);
            Buy(msg.sender, contributionInWei, rewardTransferAmount);
            if (refundInWei > 0) {
                msg.sender.transfer(refundInWei);
            }
        }
    
        function beneficiaryMultiSigWithdraw() external onlyOwner {
            checkGoalReached();
            require(areFundsReleasedToBeneficiary && (amountRaisedInWei >= fundingMinCapInWei));
            beneficiaryWallet.transfer(this.balance);
        }
    
        function checkGoalReached() public returns (bytes32 response) { // return crowdfund status to owner for each result case, update public constant
            // update state & status variables
            require (isCrowdSaleSetup);
            if ((amountRaisedInWei < fundingMinCapInWei) && (block.timestamp <= fundingEndTime && block.timestamp >= fundingStartTime)) { // ICO in progress, under softcap
                areFundsReleasedToBeneficiary = false;
                isCrowdSaleClosed = false;
                return "In progress (Eth < Softcap)";
            } else if ((amountRaisedInWei < fundingMinCapInWei) && (block.timestamp < fundingStartTime)) { // ICO has not started
                areFundsReleasedToBeneficiary = false;
                isCrowdSaleClosed = false;
                return "Crowdsale is setup";
            } else if ((amountRaisedInWei < fundingMinCapInWei) && (block.timestamp > fundingEndTime)) { // ICO ended, under softcap
                areFundsReleasedToBeneficiary = false;
                isCrowdSaleClosed = true;
                return "Unsuccessful (Eth < Softcap)";
            } else if ((amountRaisedInWei >= fundingMinCapInWei) && (tokensRemaining == 0)) { // ICO ended, all tokens gone
                areFundsReleasedToBeneficiary = true;
                isCrowdSaleClosed = true;
                return "Successful (LOL >= Hardcap)!";
            } else if ((amountRaisedInWei >= fundingMinCapInWei) && (block.timestamp > fundingEndTime) && (tokensRemaining > 0)) { // ICO ended, over softcap!
                areFundsReleasedToBeneficiary = true;
                isCrowdSaleClosed = true;
                return "Successful (Eth >= Softcap)!";
            } else if ((amountRaisedInWei >= fundingMinCapInWei) && (tokensRemaining > 0) && (block.timestamp <= fundingEndTime)) { // ICO in progress, over softcap!
                areFundsReleasedToBeneficiary = true;
                isCrowdSaleClosed = false;
                return "In progress (Eth >= Softcap)!";
            }
        }
    
        function refund() external { // any contributor can call this to have their Eth returned. user's purchased tokens are burned prior refund of Eth.
            checkGoalReached();
            //require minCap not reached
            require ((amountRaisedInWei < fundingMinCapInWei)
            && (isCrowdSaleClosed)
            && (now > fundingEndTime)
            && (fundValue[msg.sender] > 0));
    
            //burn user's token balance, refund Eth sent
            uint256 ethRefund = fundValue[msg.sender];
            fundValue[msg.sender] = 0;
            Burn(msg.sender, fundValue[msg.sender]);
    
            //send Eth back, burn tokens
            msg.sender.transfer(ethRefund);
            Refund(msg.sender, ethRefund);
        }
    
        function burnRemainingTokens() onlyOwner external {
            // require(now > fundingEndTime);
            uint256 tokensToBurn = tokenReward.balanceOf(this);
            tokenReward.burn(tokensToBurn);
        }
    }
    

I really need some help ^^

bumped to the homepage by Community yesterday

This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

0

I don't see any issues with your code right away, so I suggest you troubleshoot it - comment out everything in Buytokens method, deploy and send eth to it. See if it errs. Then uncomment line by line, deploying and testing every time. And see on which line it starts complaining about gas.

In order to do that, I would suggest you run a local ETH blockchain using Ganache (http://truffleframework.com/ganache/) - this way you don't need to wait for a test network to mine your transactions )they will be mined almost instantly) and you get 100 ETH for your account when you start it, so you don't need to mine it or ask for it.

Also, get familiar with truffle framework - it's an ethereum development framework that allows you to deploy and test your smart contracts to the local blockchain, as well as write and execute unit tests.

Actually, a unit test will greatly help you troubleshoot your issue following the steps above.

  • I can't find what's wrong, i have the same issue using multiples accounts to send ether, that gas cost is too high :/ – DrSheep Mar 1 '18 at 11:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.