0

I'm creating a token that generates new tokens every time ETH is sent to it. It takes those newly generated tokens and sends them to the wallet address that sent the ETH. The maxTokens is 40mil. The RATE is 20mil (trying to keep things simple for my test). It's pretty straightforward.

The issue I'm encountering with my test contract is that trying to send 1 ETH is fine and the transaction goes through. Trying to send a greater amount, like say 1.5, produces this warning: "Transaction Error. Exception thrown in contract code. Gas limit set dangerously high. Approving this transaction is likely to fail."

After playing around for a while I realized that I could send smaller amounts of ETH that would go through after sending the 1ETH. However, the closer I got to the max tokens I would get the above mentioned error.

Can anyone explain why I am getting this error? I can't understand why an error is producing when someone sends an amount of ETH that is relatively close to the maxTokens.

Edit: I have successfully been able to buy up to 39,999,700 of the tokens. However, I have to keep buying smaller amounts each time or else I get the above mentioned errors.

pragma solidity ^0.4.11;

import './IERC20.sol';
import './SafeMath.sol';

contract ChekOutToken is IERC20 {

using SafeMath for uint256;

uint public _totalSupply = 0;

string public constant symbol = "CHEKS";
string public constant name = "ChekOut Token";
uint8 public constant decimals = 18;

// 1 ETH = 1000 CHEKS
uint256 public constant RATE = 20000000;

// Sets Maximum Tokens to be Created
uint256 public constant maxTokens = 40000000000000000000000000;

address public owner;

mapping (address => uint256) public balances;
mapping(address => mapping(address => uint256)) allowed;

function () payable{
    createTokens();
}

function ChekOutToken(){
    owner = msg.sender;
}

function createTokens() payable{
    require(msg.value > 0);
    require(_totalSupply.add(tokens) <= maxTokens);
    uint256 tokens = msg.value.mul(RATE);
    balances[msg.sender] = balances[msg.sender].add(tokens);
    _totalSupply = _totalSupply.add(tokens);
    owner.transfer(msg.value);
    require(_totalSupply.add(tokens) <= maxTokens);
}

function totalSupply() public constant returns (uint256 totalSupply) {
    return _totalSupply;
}

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

function transfer(address _to, uint256 _value) public returns (bool success) {
    require(balances[msg.sender] >= _value && _value > 0);
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    Transfer(msg.sender, _to, _value);
    return true;
}

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    require(allowed[_from][msg.sender] >= _value && balances[_from] >= _value && _value > 0);
    balances[_from] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    Transfer(_from, _to, _value);
    return true;
}

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];
}

event Transfer(address indexed _from, address indexed _to, uint256 _value);

event Approval(address indexed _owner, address indexed _spender, uint256 _value);

}
1

I see two issues, and I think the second is the source of your error:

function createTokens() payable{
    require(msg.value > 0);
    require(_totalSupply.add(tokens) <= maxTokens);
    uint256 tokens = msg.value.mul(RATE);
    balances[msg.sender] = balances[msg.sender].add(tokens);
    _totalSupply = _totalSupply.add(tokens);
    owner.transfer(msg.value);
    require(_totalSupply.add(tokens) <= maxTokens);
}

The line require(_totalSupply.add(tokens) <= maxTokens); occurs twice. Each time is problematic:

  1. The first time, tokens has not yet been assigned a value. (I was surprised this even compiled, but apparently variable declarations are hoisted?) So this checks adding 0, which doesn't do what you want.
  2. The second time, you've already added tokens to _totalSupply so you're effectively checking "Can I add tokens twice and still stay under maxTokens?"

I would fix the function by moving the earlier require to after the computation of tokens and getting rid of the require at the end:

function createTokens() payable{
    require(msg.value > 0);
    uint256 tokens = msg.value.mul(RATE);
    require(_totalSupply.add(tokens) <= maxTokens);
    balances[msg.sender] = balances[msg.sender].add(tokens);
    _totalSupply = _totalSupply.add(tokens);
    owner.transfer(msg.value);
}
  • You solved it! It works fine now. Thank you for pointing out the double usage of the require function. I feel silly because I thought I deleted the first one, but obviously didn't... – ChekOut Jan 31 '18 at 21:41

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.