I am learning solidity and want to transfer tokens to others in my contract. But something blocked the way. Hope someone to help me. Below is my code:

pragma solidity >= 0.8.0;

contract Test {

    bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));

    constructor() {

    function safeTransfer(address token, address to, uint value) public {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TRANSFER_FAILED');

And these are the arguments I pass to safeTransfer in remix on the goerli testnet.

enter image description here

token: 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6, which is WETH.

And here is the error message.

enter image description here

I do not understand why this fails. I've tried multiple tokens and all of them just failed with the error message TRANSFER_FAILED

I am confident there are enough WETH token on the account I call this function.

1 Answer 1


When you call the function safeTransfer on contract Test, the Test contract forwards your message and the msg.sender address changes to the Test contract's address. Therefore, the Token expects Test contract to have some tokens available.

You can choose one of the two methods explained below to proceed:

  • Send some tokens to the Test contract address.
  • Give the Test contract some allowance and change it to call safeTransferFrom to forward your tokens for you.
  • Thank you for your answer. I know what is wrong. But what if I want to implement a contract that when other people call this function, a certain amount of tokens can be transferred to this contract. How can I achieve it?
    – Libra
    Feb 18 at 6:28
  • 1
    You need to write a function that does token.safeTransferFrom(msg.sender, address(this), amount). This transfers amount from msg.sender to the contract. However, it would only succeed if the msg.sender already gave enough allowance to your contract's address.
    – Allarious
    Feb 18 at 17:27

Your Answer

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

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