When using contract calls with an ERC-20 token things get messy. Let me explain:

There are 3 scenarios for token transfers:

1.- User A sends tokens to User B

2.- An ICO contract sends tokens to a buyer

3.- An asset contract sends buyer's tokens to an asset seller

By using the ERC-20 token transfer() method cases 1 and 2 are covered.

function transfer(address _to, uint256 _amount) public returns (bool success) {
    balances[msg.sender] -= _amount;
    balances[_to] += _amount;

Being msg.sender, User A (case #1) and ICO contract (case #2) the tokens are transferred successfully.

But transfer() method cannot solve case #3, because msg.sender is not the user (having tokens) that sends the transaction, but the asset contract (having no tokens) acting as middle-man.

This third case requires the use of tx.origin instead of msg.sender, so the tokens would came from the user that originates the transaction.

Any idea how to solve the 3 cases preserving the ERC-20 transfer method as unique? Thx!


  • 1
    This is a limitation of ERC-20. There's a proposal in ERC-223 to add a callback mechanism to notify an external contract when it has been approved. Also use of tx.origin is discouraged by Ethereum developers, for example in this case it will not work with multisig wallets.
    – Ismael
    Commented Sep 30, 2017 at 16:46

1 Answer 1


I'm a little unsure of what you're asking. Lets take etherdelta for an example "asset contract". Etherdelta acts as a middleman, yes, but to place an order for an ethereum token, you will send ethereum to their contract. So the etherdelta contract itself is actually transferring the tokens to you, and the ethereum to the person who you bought the tokens from.

As you have shown, a middle-man asset contract that doesn't actually access the tokens wouldn't work in this way. Perhaps you could use the approve() and transferFrom() ERC20 functions if you required the asset contract to not touch the tokens.

Here is the ERC20 token standard for reference: https://theethereum.wiki/w/index.php/ERC20_Token_Standard

  • Thank you for your answers. By sending the tokens to the contract the buy asset operation would require two transactions: 1.- send tokens to the contract and 2.- contract sends tokens to the seller. But I need this operation to be performed with just 1 atomic transaction. The other solution, using approve() and transferFrom() endpoints behaves similarly in the sense that 2 transactions are required. Commented Sep 30, 2017 at 9:52
  • 1
    I'm not sure that this is possible in one transaction in the way that you are defining a transaction. However, the buyer could send the tokens to the contract address, and the contract executes code that then forwards the tokens to the seller. This would all happen in one block, and in one self-contained contract code execution. So effectively this would be one transaction, depending on how you are defining a transaction.
    – Alex
    Commented Oct 2, 2017 at 2:39

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.