EatTheBlocks Forum

ERC20 Smart Contract Integration

I’m adapting my B2B application to use Dai ERC20 tokens using the OpenZeppelin framework.

The scenario is this:

  • User can deposit Dai tokens from his wallet to his Smart Contract balance in order to transact business

  • User can withdraw Dai tokens from his Smart Contract balance to his wallet

This all works as expected with Ether but not with ERC20 tokens.

I have a faucet that generates Dai and prefunds accounts for testing. I point the accounts in MetaMask to the Dai mock contract and the Dai balance appears as expected:

I can withdraw Dai tokens from the Smart Contract to the wallet address using the ‘transfer’ function.

What I cannot do is deposit tokens from the wallet address into the Smart Contract.

Based on what I’ve read you use ‘transferFrom’ to move tokens from the wallet to the Smart Contract. Is this correct?

In order to move tokens using transferFrom you first need to approve the number of tokens you want to transfer using the ‘approve’ function. When I do this I get the screen below in MetaMask:

I call the approve function as follows:

I hard coded the contract address and values for testing purposes.

I interpret this as “Message Sender (wallet address accounts[0]) approves contract address to spend amount ‘a’.

frontend:

const receipt = await contract1.methods.approve(‘0xe2b81726E4Fa23db414bA1c8FB5F08982c94F2e6’,a).send({from:accounts[0]})

contract:

function approve(address spender, uint amount) external {

dai.approve(spender,1000000000000000000);

}

When I do this however the Dai token disappears from the wallet address and when I call the ‘allowance’ function it returns 0.

frontend:

const all = await contract1.methods.getAllowance(accounts[0],‘0xe2b81726E4Fa23db414bA1c8FB5F08982c94F2e6’).call({ from: accounts[0] });

contract:

function getAllowance(address msg_sender, address spender) external view returns (uint){

return dai.allowance(msg_sender, spender);

}

I’ve tried every combination but can’t see what I’m missing.

Is this even the correct functionality or should I be using some other method to transfer tokend from a wallet address to a Smart Contract?

I recommend to write tests in Truffle to validate your logic first, and only after add the frontend.

For token tranfers, the logic is as such:

  1. a token owner approves a smart contract to spend X tokens
  2. a token owner call the function of a smart contract (ex: deposit())
  3. The deposit() function of the smart contract calls transferFrom() to transfer tokens from the owner to itself

Got it. Thanks for clarifying the process.

1 Like