0

I have a case here. Created a contract and sent some tokens to it. As of now, the contract is of not usable. The contract had destroy function as below.

  function destroy() onlyOwner {
    // Transfer tokens back to owner
    uint256 balance = token.balanceOf(this);
    assert(balance > 0);
    token.transfer(owner, balance);
  }

But, when the token contract was created, the transfer function was coded as below.

/**
* Internal transfer, only can be called by this contract
*/
function _transfer(address _from, address _to, uint _value) internal {
    // Prevent transfer to 0x0 address. Use burn() instead
    require(_to != 0x0);
    // Check if the sender has enough
    require(balanceOf[_from] >= _value);
    // Check for overflows
    require(balanceOf[_to] + _value > balanceOf[_to]);
    // Save this for an assertion in the future
    uint previousBalances = balanceOf[_from] + balanceOf[_to];
    // Subtract from the sender
    balanceOf[_from] -= _value;
    // Add the same to the recipient
    balanceOf[_to] += _value;
    Transfer(_from, _to, _value);
    // Asserts are used to use static analysis to find bugs in your code. They should never fail
    assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}

The line require(balanceOf[_to] + _value > balanceOf[_to]); is not allowing to destory as the require always fails during send all the available tokens.

Had created another contract just test the drain function with a different name as below which worked properly. And the contract in consideration was not coded like this (that has the destroy function as above)

  /**
   * @notice Terminate contract and refund to owner
   */
  function withdraw() onlyOwner external {
    address myAddress = this;
    if(myAddress.balance > 0)
        owner.transfer(myAddress.balance);
    uint256 tokBalance = token.balanceOf(this);
    tokBalance = tokBalance - (1 wei);
    if(tokBalance > 0)
        token.transfer(owner, tokBalance);
  }

Is there a way to burn/get back tokens from that contract? Though we can freeze the account, that doesn't help as we want to burn the tokens. Second contract (from where to withdraw or burn token) is here and 0x1798F533e0cE9501dac8a831A0b02A4f35304FFd is the address of it

6
  • Can you explain why that require is failing? Is the _to account's balance overflowing?
    – user19510
    Commented Mar 24, 2018 at 5:54
  • Is it not supposed to be >= in the condition? because of just > this condition never met. I mean it supposed to be require(balanceOf[_to] + _value >= balanceOf[_to]);
    – Rajesh
    Commented Mar 24, 2018 at 7:53
  • I do think >= is better, but only because ERC20 usually allows transfers of 0. It shouldn't cause a non-zero transfer to fail.
    – user19510
    Commented Mar 24, 2018 at 7:54
  • But am not able to execute that function, getting that high gas warning, and even if I try, the transaction gets failed
    – Rajesh
    Commented Mar 24, 2018 at 7:55
  • 1
    The token contract is verified here etherscan.io/address/…. And same contract available in rinkeby in which the withdraw failed. Transaction is here rinkeby.etherscan.io/tx/…. Had also created another contract with similar function with a little change to keep 1 Wei in the contract worked. Updated that in the question.
    – Rajesh
    Commented Mar 24, 2018 at 8:53

1 Answer 1

1

From your link the issue is that you override _transfer in RETNToken

function _transfer(address _from, address _to, uint _value) internal {
    require (_to != 0x0);                               // Prevent transfer to 0x0 address. Use burn() instead

--->require (balanceOf[_from] > _value);                // Check if the sender has enough

    require (balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows
    require(!frozenAccount[_from]);                     // Check if sender is frozen
    require(!frozenAccount[_to]);                       // Check if recipient is frozen
    balanceOf[_from] -= _value;                         // Subtract from the sender
    balanceOf[_to] += _value;                           // Add the same to the recipient
    Transfer(_from, _to, _value);
}

The solution is to replace that line by the correct one

require (balanceOf[_from] >= _value);
7
  • So, how do I get the tokens back from that another contract?
    – Rajesh
    Commented Mar 25, 2018 at 8:23
  • The solution is to replace that line by the correct: require (balanceOf[_from] >= _value);. If the contracts are already deployed there's not much you can do about it, if it is programmed in the contract you can approve a third party to do the transfer.
    – Ismael
    Commented Mar 25, 2018 at 15:03
  • The contracts are already deployed. Can you explain bit more about approve third party to do transfer in the contract?
    – Rajesh
    Commented Mar 26, 2018 at 4:49
  • ERC20 tokens support using approve for token owners allow another third party make transferFrom from the owner balance. If your contract was programmed to call approve you can use it,if that is not the case then your tokens are locked inside of it.
    – Ismael
    Commented Mar 26, 2018 at 7:24
  • But the balance are not with the owner. The token contract has the approve, but the contract in discussion just has destroy. Does this mean, no way to withdraw it? github.com/RetainlyInc/retn-pre-ico-contract/blob/master/… is the code to the contract and 0x1798F533e0cE9501dac8a831A0b02A4f35304FFd is the address of it
    – Rajesh
    Commented Mar 27, 2018 at 5:40

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.