1

Let's say I create an ERC20 token, and I want to collect 1,000 wei commission any time it replaces hands.

Here's Zeppelin transferFrom code:

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

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

Is this the right way to override it to achieve my goal?

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

    // make sure I can collect 1000 wei commission
    require(msg.sender.balance >= 1000)

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);

    // collect the commission (assume myAddress is set to my address)
    myAddress.transfer(1000);

    emit Transfer(_from, _to, _value);
    return true;
  }

And now can I assume whoever the msg.sender is, be it a smart contract (of an exchange perhaps?) or the _to, will have to pay additional 1000 wei on top of the gas?

1 Answer 1

1

Your approach of sending 1000 wei to some address via myAddress.transfer(1000); requires the smart contract to have received that payment at some point. This could even be in the same transaction but note that standard ERC20 transfers are not payable. Instead, I would suggest to collect your commission in tokens and not in Ether. Note that your code does not reflect the current version of the OpenZeppelin standard ERC20 token.

You could then extend the transfer and transferFrom functions as follows (note that I also use Ownable and the commission goes to the Owner):

pragma solidity ^0.4.24;

import "./StandardToken.sol";
import "./Ownable.sol";

contract CommissionToken is StandardToken, Ownable {

  uint256 public commission = 1000;

  // override
  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  )
    public
    returns (bool)
  {
    balances[_from] = balances[_from].sub(commission);
    balances[owner] = balances[owner].add(commission);
    return super.transferFrom(_from, _to, _value);
  }

  // override
  function transfer(
    address _to,
    uint256 _value
  )
    public
    returns (bool)
  {
    balances[msg.sender] = balances[msg.sender].sub(commission);
    balances[owner] = balances[owner].add(commission);
    return super.transfer(_to, _value);
  }
}
2
  • Since you modify balances you should emit a Transfer event.
    – Ismael
    Commented Jun 16, 2018 at 14:07
  • What your answer suggest and is probably what I failed to understand is that myAdress.transfer transfers ETH from the contract's balance itself and not from the account that signed the transaction? I thought it takes the ETH from the account that signed the transaction... Is there a way to charge the account that signed the transaction? And how would it then be displayed to the end user in MetaMask?
    – shaharsol
    Commented Jun 18, 2018 at 5:15

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.