0

I have some problems with my smart contract for my dApp. I want to sell the tokens whenever someone sends ether to the smart contract and will be given some tokens based on their contributions.

When ever I deploy the contract, I get an error that says something like the contract does not contain any data, but that dissapears immediately.

Everything all right, until I want to send ether to the contract address. When I try to send it, I get another error: It seems like this transaction will fail.

Hope you can help me asap! :)

Below I've provided the code for the smart contract:

pragma solidity ^0.4.18;

contract SafeMath {
    function safeAdd(uint256 x, uint256 y) internal pure returns(uint256) {
        uint256 z = x + y;
        assert((z >= x) && (z >= y));
        return z;
    }

    function safeSub(uint256 x, uint256 y) internal pure returns(uint256) {
        assert(x >= y);
        uint256 z = x - y;
        return z;
    }

    function safeMult(uint256 x, uint256 y) internal pure returns(uint256) {
        uint256 z = x * y;
        assert((x == 0) || (z / x == y));
        return z;
    }
}

contract Token {
    function balanceOf(address _owner) public constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) public returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
    function approve(address _spender, uint256 _value) public returns (bool success);
    function allowance(address _owner, address _spender) public constant returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

contract StandardToken is Token {
    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    function transfer(address _to, uint256 _value) public returns (bool success) {
        if(balances[msg.sender] >= _value && _value > 0) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else {
            return false;
        }
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
      if(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
            balances[_to] += _value;
            balances[_from] -= _value;
            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else {
            return false;
        }
    }

    function balanceOf(address _owner) public constant returns (uint256 balance) {
        return balances[_owner];
    }

    function approve(address _spender, uint256 _value) public returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }
}

contract VCONAToken is StandardToken, SafeMath {
    string public constant name = 'VCONA Token';
    string public constant symbol = 'VCONA';
    uint256 public constant decimals = 0;

    address public ethFundDeposit;

    bool public isFinalized;
    uint256 public totalSupply;
    uint256 public constant tokenExchangeRate = 100000;
    uint256 public constant tokenCreationCap =  1000000;

    event LogRefund(address indexed _to, uint256 _value);
    event CreateVCONA(address indexed _to, uint256 _value);

    function VCONAToken(address _ethFundDeposit) public {
        isFinalized = false;
        ethFundDeposit = _ethFundDeposit;
        totalSupply = 0;
    }

    function () payable external {
        require(isFinalized != false);
        require(msg.value != 0);

        uint256 tokens = safeMult(msg.value, tokenExchangeRate);
        uint256 checkedSupply = safeAdd(totalSupply, tokens);

        require(tokenCreationCap >= checkedSupply);

        totalSupply = checkedSupply;
        balances[msg.sender] += tokens;
        CreateVCONA(msg.sender, tokens);
    }

    function finalize() external {
        require(isFinalized != false);
        require(msg.sender == ethFundDeposit);
        require(totalSupply == tokenCreationCap);
        isFinalized = true;

        if(!ethFundDeposit.send(this.balance)) revert();
    }

    function refund() external {
        require(isFinalized != false);
        uint256 vconaValue = balances[msg.sender];
        require(vconaValue > 0);
        balances[msg.sender] = 0;
        totalSupply = safeSub(totalSupply, vconaValue);
        uint256 ethValue = vconaValue / tokenExchangeRate;
        LogRefund(msg.sender, ethValue);

        if(!msg.sender.send(ethValue)) revert();
    }
}

1 Answer 1

0

Two things:

Your are checking for finalized to be true, finalized must be false for the contract to be in "crowdsale" mode.

Second you are not converting msg.value to ether so any amount greater than 10 wei will put you over tokenCreationCap

This fallback will work:

uint tokenExchangeRate = 0.0001 ether //(10k tokens for 1 ether)


 function () payable external {
        require(!isFinalized);
        require(msg.value != 0 && msg.value >= tokenExchangeRate);

        uint256 tokens = msg.value / tokenExchangeRate 
        uint256 checkedSupply = safeAdd(totalSupply, tokens);

        require(tokenCreationCap >= checkedSupply);

        totalSupply = checkedSupply;
        balances[msg.sender] += tokens;
        CreateVCONA(msg.sender, tokens);
    }
5
  • Thanks. It works now. But I came to another problem. How should I handle 0 decimals? It works only when I send like 1 ether, but not with decimals. Sending for example 0.2 ETH, at the 100.000 token exchange rate, it should give me 20.000 tokens, but it gives nothing. Note, I want no decimals to the tokens. Fixed numbers: 5, 1000, 20000, etc. Also, I modified a little bit the code: pastebin.com/ekPt2vUa
    – xSuVe
    Mar 21, 2018 at 12:08
  • Uint can't take decimals. Therefore you should define tokenExchangeRate nominated in 'ether' or 'wei' for example. Then divide msg.value by exchangeRate. Here's an example: github.com/kyriediculous/ERC223-tokensale/blob/master/… I have also edited the answer.
    – Nico
    Mar 21, 2018 at 12:31
  • That should be applied to the withdraw() function too? Seems like its not working properly. Updated: pastebin.com/ZY50PNa3 Edit: withdrawing for example 0.2 ETH, so decimals
    – xSuVe
    Mar 21, 2018 at 15:58
  • Regarding your withdraw function: The parameter takes an amount in wei and can not take decimals (amount in eth smaller than 1) as it is a uint. I'm not aware that this is possible otherwise because fixed point isn't fully supported yet: solidity.readthedocs.io/en/latest/… By the way you should typecast 'this' to address so 'address(this).balance '
    – Nico
    Mar 21, 2018 at 16:14
  • Maybe another way to withdraw the ETH from the contract before finalizing it? Maybe it works without specifying a desired amount and just withdraw everything that has been contributed until then? I really appreciate your support, Nico! Thanks for everything.
    – xSuVe
    Mar 21, 2018 at 16:30

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.