3

Can't really use the transfer function as it is written. It assumes the owner uses it. So made a new function for the "minting" function for the faucet to use. Not sure why the compiler message is so cryptic.

totalSupply_ = totalSupply_.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
emit Transfer(address(0), _to, _amount);

Trying to create a Faucet for my ERC-20 Token, and getting a "Gas Estimation Failed" when running my dripToken function which looks like this (UPDATED):

function dripToken() public {
  require(faucetStatus);
  if(!checkStatus(msg.sender)) revert();
  tokenInstance.updateSupply(oneToken);
  updateStatus(msg.sender, oneMinute);
  tokenInstance.transfer(msg.sender, oneToken);
}

I have narrowed it down to the line with the transfer call which causes the error. I now deploy my ERC-20 Token and pass that into the faucet contract on the following way:

constructor(string _fname, address _tokenInstance) public {
  tokenInstance = MyToken(_tokenInstance);
  faucetName = _fname;
  faucetStatus = true;

  emit FaucetOn(faucetStatus);
}

My Token transfer function is from https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/StandardToken.sol I just noticed I get a compiler warning on the transfer function which hints at the problem, but I don't understand why (yet). Here is the warning:

Gas requirement of function StandardToken.transfer(address,uint256) high: infinite. If the gas requirement of a function is higher than the block gas limit, it cannot be executed. Please avoid loops in your functions or actions that modify large areas of storage (this includes clearing or copying arrays in storage)

function transfer(address _to, uint256 _value) public returns (bool) {
  require(_value <= balances[msg.sender]);
  require(_to != address(0));

  balances[msg.sender] = balances[msg.sender].sub(_value);
  balances[_to] = balances[_to].add(_value);
  emit Transfer(msg.sender, _to, _value);
  return true;
}

I create my Token in the following way. I now initialize it with a small supply.

contract MyToken is StandardToken {
  string public name;                   
  uint8 public decimals;                
  string public symbol;  

  constructor() public {  
    StandardToken.balances[msg.sender] = 1000000000000000000;
    StandardToken.totalSupply_ = 1000000000000000000;                        
    name = "My Token";                             
    decimals = 18; 
    symbol = "MY";      
  }
}

Posted my code on google drive: https://drive.google.com/open?id=1EvKEVhD8bR2oKS2W1XNRQpTqVbieUcmC

7
  • 1
    It's hard to know without seeing the implementation of transfer, but I would guess that it fails if the contract itself doesn't have a high enough balance. You might just want totalSupply_ += oneToken; balanceOf[msg.sender] += oneToken; emit Transfer(0, msg.sender, oneToken);.
    – user19510
    Aug 18, 2018 at 3:06
  • I tried to swap the lines as you suggested. Still getting the same error. What does emit Transfer do? Is that a different transfer function? I have removed my inheritance as well, and now passing in the token contract into the faucet. I updated the original post with more code.
    – Tom Berge
    Aug 18, 2018 at 9:21
  • Transfer is an event that should be emitted by your token any time a token is transferred. (By convention, an event is emitted showing a transfer from address 0 when new tokens are minted.)
    – user19510
    Aug 18, 2018 at 9:24
  • Noticed I get a warning regarding the transfer function, regarding high gas. Not sure what is causing it (yet). Pasted the warning in my op.
    – Tom Berge
    Aug 18, 2018 at 11:52
  • If you share enough code to reproduce the issue, I'd be happy to try it out. It's a little tedious just making guesses.
    – user19510
    Aug 18, 2018 at 14:57

2 Answers 2

1

See top of OP for answer. I think it was the require block that failed. Not sure why the compiler is so cryptic about it.

0

You must specify the address that is calling transfer. For example, if the you are trying to transfer an ERC20 token, the code would be as follows:

ERC20TokenAddress.transfer(msg.sender, oneToken);

Without the leading address, the EVM doesn't know what is being transferred.

4
  • 1
    How do I get the address? Currently I am defining the faucet contract in the following way: contract Faucet is ERC20Token. Would it be better then to deploy the ERC20Token contract and then pass the address in to the Faucet contract through the constructor and just remove the inheretance?
    – Tom Berge
    Aug 17, 2018 at 20:09
  • Yes, you can do that. The other option is to have a setAddress() function. It would look like function setAddress(address tokenAddress) onlyOwner { ERC20TokenAddress = tokenAddress; } Aug 17, 2018 at 20:11
  • There's nothing wrong with the same contract being the ERC20 token and having the dripToken() function.
    – user19510
    Aug 18, 2018 at 3:05
  • Noticed I get a warning regarding the transfer function, regarding high gas. Not sure what is causing it (yet). Pasted the warning in my op.
    – Tom Berge
    Aug 18, 2018 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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