logoAcademy

ERC-20 and Smart Contracts

Transfer an ERC-20 Token to a smart contracts

Transferring ERC-20 tokens to a smart contract involves a few steps, including setting an allowance and then using the transferFrom function to move the tokens. This process ensures that the smart contract can only withdraw the amount of tokens you've explicitly approved.

First, let's look at the necessary code to achieve this. We'll use the same basic ERC-20 token contract that we used previously.

Smart Contract Receiving an ERC20

We need a smart contract that will receive the tokens:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts@4/token/ERC20/IERC20.sol"; //[!code highlight]
 
contract TokenReceiver {
    IERC20 public token;
 
    constructor(address tokenAddress) {
        token = IERC20(tokenAddress);
    }
 
    function receiveTokens(address from, uint256 amount) public {
        require(token.transferFrom(from, address(this), amount), "Transfer failed"); //[!code highlight]
    }
}

In this contract, the receiveTokens function allows the contract to receive tokens from a specified address. It uses the transferFrom function of the ERC-20 token standard.

Deploy ERC20 receiver

Let's deploy this ERC20receiver contract

forge create --rpc-url local-c --private-key $PK src/ICTT/01-tokens/02-erc20-receiver.sol:TokenReceiver --constructor-args $ERC20_CONTRACT_SUBNET

And save the deployment address in an environment variable

export ERC20_RECEIVER_SUBNET=0x...

Approve token expense

Now to send Tokens to that contract, the Receiver contracts needs to be allowed to take funds on behalf of the user. Therefore, we need to allow our receiver contract as spender on the TOK interface.

cast send $ERC20_CONTRACT_SUBNET --private-key $PK "approve(address,uint256)" $ERC20_RECEIVER_SUBNET 20ether --rpc-url myblockchain

Transfer tokens to Smart Contract

Finally let's transfer tokens to this contract

cast send $ERC20_RECEIVER_SUBNET --private-key $PK "receiveTokens(address,uint256)" $EWOQ 2ether --rpc-url myblockchain

Confirm transfer

cast call $ERC20_CONTRACT_SUBNET "balanceOf(address)(uint256)" $ERC20_RECEIVER_SUBNET --rpc-url myblockchain
Updated:

On this page

Edit on Github