1

I'm testing a Crowdsale contract (C) which send tokens of an already deployed contract (T). The idea is to send an amount of tokens to C from T, and then selling them for Ether, but nothing is working, C doesn't even receive the Ether. Here's the Crowdsale contract:

pragma solidity ^0.4.13;

contract ForeignToken {
    function balanceOf(address _owner) constant returns (uint256);
    function transfer(address _to, uint256 _value) returns (bool);
}

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

contract Token { 
    function issue(address _recipient, uint256 _value) returns (bool success);
    function totalSupply() constant returns (uint256 supply);
    function unlock() returns (bool success);
}

contract TokenCrowdsale {

    using SafeMath for uint256;

    // Crowdsale details
    address public beneficiary;                     
    address public creator;                         
    address public confirmedBy;                     
    uint256 public maxSupply = 15000000e8;    
    uint256 public minAcceptedAmount = 10 finney;   
    bool public purchasingAllowed = false;


    // Eth to token rate
    uint256 public rate = 2000;

    enum Stages {
        PreSale,
        InProgress,
        Ended,
        Withdrawn
    }

    Stages public stage = Stages.PreSale;

    // deployed token
    Token public deplToken;

    // Invested balances
    mapping (address => uint256) balances;

    /**
    * Throw if at stage other than current stage
    * 
    * @param _stage expected stage to test for
    */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    /**
    * Throw if sender is not beneficiary
    */
    modifier onlyBeneficiary() {
        require(beneficiary == msg.sender);
        _;
    }

    /** 
    * Get balance of `_investor` 
    * 
    * @param _investor The address from which the balance will be retrieved
    * @return The balance
    */
    function balanceOf(address _investor) constant returns (uint256 balance) {
        return balances[_investor];
    }


    function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
        purchasingAllowed = false;
        stage = Stages.Ended;
    }

    function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    /**
    * Constructor
    *
    * @param _tokenAddress The address of the token contact
    * @param _beneficiary  The address of the wallet for the beneficiary  
    * @param _creator      The address of the wallet for the creator 
    */
    function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
        deplToken = Token(_tokenAddress);
        beneficiary = _beneficiary;
        creator = _creator;
    }

    /**
    * For testing purposes
    *
    * @return The beneficiary address
    */
    function confirmBeneficiary() onlyBeneficiary {
        confirmedBy = msg.sender;
    }


    /**
    * Transfer raised amount to the beneficiary address
    */
    function withdraw() onlyBeneficiary atStage(Stages.Ended) {
        uint256 ethBalance = this.balance;
        beneficiary.transfer(ethBalance);
        stage = Stages.Withdrawn;
    }

    /**
    * Receives Eth and issue tokens to the sender
    */
    function () payable atStage(Stages.InProgress) {

        require(purchasingAllowed);

        address investor = msg.sender;
        uint256 received = (msg.value).div(10e8);

        // Enforce min amount
        require(received >= minAcceptedAmount);
        uint256 tokens = (received).mul(rate);

        require(tokens > 0);

        require(deplToken.issue(investor, tokens));

        balances[investor] = balances[investor].add(received);
        //raised += received;

        // Check totalSupply raised
        if (deplToken.totalSupply() >= maxSupply) {
            stage = Stages.Ended;
        }
    }

    function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
        ForeignToken token = ForeignToken(_tokenContract);
        uint256 amount = token.balanceOf(address(this));
        return token.transfer(beneficiary, amount);
    }
}

Any help is appreciated, thank you

EDIT: after suggestions in comments, I managed to receive ETH on the Crowdsale contract, but it is not issuing the tokens. Here's the code:

pragma solidity ^0.4.13;

contract ForeignToken {
    function balanceOf(address _owner) constant returns (uint256);
    function transfer(address _to, uint256 _value) returns (bool);
}

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

contract Token { 
    function issue(address _recipient, uint256 _value) returns (bool success);
    function totalSupply() constant returns (uint256 supply);
    function unlock() returns (bool success);
}

contract TokenCrowdsale {

    using SafeMath for uint256;

    // Crowdsale details
    address public beneficiary;                     
    address public creator;                         
    address public confirmedBy;                     
    uint256 public maxSupply = 15000000e8;    
    uint256 public minAcceptedAmount = 10 finney;
    bool public purchasingAllowed = false;
    uint256 public totalSupply = 0;

    // Eth to token rate
    uint256 public rate = 2000;

    enum Stages {
        PreSale,
        InProgress,
        Ended,
        Withdrawn
    }

    Stages public stage = Stages.PreSale;

    // deployed token
    Token public deplToken;

    // Invested balances
    mapping (address => uint256) balances;

    /**
    * Throw if at stage other than current stage
    * 
    * @param _stage expected stage to test for
    */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    /**
    * Throw if sender is not beneficiary
    */
    modifier onlyBeneficiary() {
        require(beneficiary == msg.sender);
        _;
    }

    /** 
    * Get balance of `_investor` 
    * 
    * @param _investor The address from which the balance will be retrieved
    * @return The balance
    */
    function balanceOf(address _investor) constant returns (uint256 balance) {
        return balances[_investor];
    }


    function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
        purchasingAllowed = false;
        stage = Stages.Ended;
    }

    function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    /**
    * Constructor
    *
    * @param _tokenAddress The address of the token contact
    * @param _beneficiary  The address of the wallet for the beneficiary  
    * @param _creator      The address of the wallet for the creator 
    */
    function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
        deplToken = Token(_tokenAddress);
        beneficiary = _beneficiary;
        creator = _creator;
    }

    /**
    * For testing purposes
    *
    * @return The beneficiary address
    */
    function confirmBeneficiary() onlyBeneficiary {
        confirmedBy = msg.sender;
    }


    /**
    * Transfer raised amount to the beneficiary address
    */
    function withdraw() onlyBeneficiary atStage(Stages.Ended) {
        uint256 ethBalance = this.balance;
        beneficiary.transfer(ethBalance);
        stage = Stages.Withdrawn;
    }

    /**
    * Receives Eth and issue tokens to the sender
    */
    function () payable atStage(Stages.InProgress) {
        require(purchasingAllowed);

        if (msg.value >= 10 finney) {
            address investor = msg.sender;
            uint256 received = (msg.value).div(10e8);
            uint256 tokens = (received).mul(rate);
            balances[investor] = balances[investor].add(tokens);
            totalSupply = (totalSupply).add(tokens);
        }

        if (totalSupply >= maxSupply) {
            purchasingAllowed = false;
            stage = Stages.Ended;
        }

    }

    function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
        ForeignToken token = ForeignToken(_tokenContract);
        uint256 amount = token.balanceOf(address(this));
        return token.transfer(beneficiary, amount);
    }
}

As you can see, I changed the "require" in the fallback function with an "if" iteration

  • Can you elaborate on "what is not working"? Can you show us how you call functions? with web3? With your wallet? – Florian Castelain Nov 23 '17 at 2:19
  • @AlxMrx it seems that your code is working...Did you try it using Mist?? – Crissi Mariam Robert Nov 23 '17 at 8:21
  • Well, I deployed it on testnet (Rinkeby) with Mist, then I sent 15M tokens to it and launched the function "enablePurchasing"; but if I try to send ETH from another wallet nothing happens, the transaction returns a "Fail" status – user19489 Nov 23 '17 at 8:38
  • you have a glitch: fuddToken doesn´t exist – Luiz Soares Nov 23 '17 at 11:22
  • Yeah sorry, it is correct in the deployed contract as deplToken, I pasted here an old code. Corrected now – user19489 Nov 23 '17 at 11:30
0

Following the suggestions and doing more research led me to find the solution. First of all I changed the

contract Token {}

to

interface Token {}

I also added an event that is then called by the fallback function to send tokens:

event sendTokens(address indexed to, uint256 value);

Finally, I cleaned the code of unused variable and added some other function not related to my problem, but useful to manage the crowdsale. Here's the final working code:

pragma solidity ^0.4.13;

contract ForeignToken {
    function balanceOf(address _owner) constant returns (uint256);
    function transfer(address _to, uint256 _value) returns (bool);
}

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

interface Token { 
    function transfer(address _to, uint256 _value) returns (bool);
    function totalSupply() constant returns (uint256 supply);
    function balanceOf(address _owner) constant returns (uint256 balance);
}

contract TokenCrowdsale {

    using SafeMath for uint256;

    // Crowdsale details
    address public beneficiary;                     
    address public creator;                         
    address public confirmedBy;                     
    uint256 public maxSupply = 15000000e8;    
    bool public purchasingAllowed = false;
    uint256 public totalSupplied = 0;

    // Eth to token rate
    uint256 public rate = 2000;

    enum Stages {
        PreSale, //0
        InProgress, //1
        Ended, //2 
        Withdrawn //3
    }

    Stages public stage = Stages.PreSale;

    // deployed token
    Token public deplToken;

    // Invested balances
    mapping (address => uint256) balances;

    /**
    * Throw if at stage other than current stage
    * 
    * @param _stage expected stage to test for
    */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    /**
    * Throw if sender is not beneficiary
    */
    modifier onlyBeneficiary() {
        require(beneficiary == msg.sender);
        _;
    }

    /** 
    * Get balance of `_investor` 
    * 
    * @param _investor The address from which the balance will be retrieved
    * @return The balance
    */
    function balanceOf(address _investor) constant returns (uint256 balance) {
        return balances[_investor];
    }


    function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
        purchasingAllowed = false;
        stage = Stages.Ended;
    }

    function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
        purchasingAllowed = true;
        stage = Stages.InProgress;
    }

    /**
    * Constructor
    *
    * @param _tokenAddress The address of the token contact
    * @param _beneficiary  The address of the wallet for the beneficiary  
    * @param _creator      The address of the wallet for the creator 
    */
    function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
        deplToken = Token(_tokenAddress);
        beneficiary = _beneficiary;
        creator = _creator;
    }

    /**
    * For testing purposes
    *
    * @return The beneficiary address
    */
    function confirmBeneficiary() onlyBeneficiary {
        confirmedBy = msg.sender;
    }


    event sendTokens(address indexed to, uint256 value);


    /**
    * Transfer raised amount to the beneficiary address
    */
    function withdraw() onlyBeneficiary atStage(Stages.Ended) {
        uint256 ethBalance = this.balance;
        beneficiary.transfer(ethBalance);
        stage = Stages.Withdrawn;
    }

    /**
    * Receives Eth and issue tokens to the sender
    */
    function () payable atStage(Stages.InProgress) {

        require(purchasingAllowed);
        if (msg.value == 0) { return; }
        uint256 weiAmount = msg.value;
        address investor = msg.sender;
        uint256 received = weiAmount.div(10e7);
        uint256 tokens = (received).mul(rate);

        if (msg.value >= 10 finney) {
            uint256 bonusToken = (tokens.div(100)).mul(20);
            tokens = tokens.add(bonusToken);
        }

        sendTokens(msg.sender, tokens);
        deplToken.transfer(investor, tokens);
        totalSupplied = (totalSupplied).add(tokens);

        if (totalSupplied >= maxSupply) {
            purchasingAllowed = false;
            stage = Stages.Ended;
        }

    }


    function tokensAvailable() constant returns (uint256) {
        return deplToken.balanceOf(this);
    }


    function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
        ForeignToken token = ForeignToken(_tokenContract);
        uint256 amount = token.balanceOf(address(this));
        return token.transfer(beneficiary, amount);
    }
}

I'm not sure if either "interface Token" or "event sendTokens", or both together, were the solutions, but it is working now; I can send ether and receive the deployed token. I've answered my own question so it will remain here as a solution if anyone else need something like this. Thank you

Your Answer

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