# Deposit USDC to smart contract

**URL:** <https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010>\
**Category:** Smart Contracts\
**Tags:** erc20\
**Created:** [March 11, 2022, 10:52am UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010 "2022-03-11T10:52:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tkh](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/tkh/32/13784_2.png) [@tkh](https://forum.openzeppelin.com/u/tkh)\
**Post date:** [March 11, 2022, 10:52am UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010/1 "2022-03-11T10:52:47Z")

</div>

I change DaiToken address to an polygon testnet usdc token address (0xe11A86849d99F524cAC3E7A0Ec1241828e332C62) but the function is not working.

End goal

1. deposit USDC to contract
2. withdraw USDC after I deposit it on step 1

```auto
pragma solidity ^0.5.0;

interface DaiToken {
    function transfer(address dst, uint wad) external returns (bool);
    function transferFrom(address src, address dst, uint wad) external returns (bool);
    function balanceOf(address guy) external view returns (uint);
}

contract TokenFarm {
    DaiToken public daiToken;
    address owner;
    mapping(address => uint) public stakingBalance;

    /*
       Kovan DAI: 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa
    */
    constructor() public {
        daiToken = DaiToken(0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa);
        owner = msg.sender;
    }

    function stakeTokens(uint _amount) public {

        // amount should be > 0
        require(_amount > 0, "amount should be > 0");

        // transfer Dai to this contract for staking
        daiToken.transferFrom(msg.sender, address(this), _amount);
        
        // update staking balance
        stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;
    }

    // Unstaking Tokens (Withdraw)
    function unstakeTokens() public {
        uint balance = stakingBalance[msg.sender];

        // balance should be > 0
        require (balance > 0, "staking balance cannot be 0");

        // Transfer Mock Dai tokens to this contract for staking
        daiToken.transfer(msg.sender, balance);

        // reset staking balance to 0
        stakingBalance[msg.sender] = 0;
    }
}

```

---

<div class="post-metadata">

**Author:** ![maxareo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/maxareo/32/11606_2.png) [@maxareo](https://forum.openzeppelin.com/u/maxareo)\
**Post date:** [March 11, 2022, 11:01am UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010/2 "2022-03-11T11:01:15Z")

</div>

You will need to let the USDC/DAI token contract approve `this` contract, because this contract will move funds on the msg.sender's behalf either from the wallet to this contract or from this contract to the wallet.

---

<div class="post-metadata">

**Author:** ![tkh](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/tkh/32/13784_2.png) [@tkh](https://forum.openzeppelin.com/u/tkh)\
**Post date:** [March 11, 2022, 11:25am UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010/3 "2022-03-11T11:25:58Z")

</div>

Thanks I am a newbie to this how could it perform the approve on usdc contract?

---

<div class="post-metadata">

**Author:** ![maxareo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/maxareo/32/11606_2.png) [@maxareo](https://forum.openzeppelin.com/u/maxareo)\
**Post date:** [March 11, 2022, 11:55am UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010/4 "2022-03-11T11:55:34Z")

</div>

The `USDC` or `DAI` contract is also an ERC20 contract. You can call the `approve` function on those contracts.

---

<div class="post-metadata">

**Author:** ![tkh](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/tkh/32/13784_2.png) [@tkh](https://forum.openzeppelin.com/u/tkh)\
**Post date:** [March 11, 2022, 1:19pm UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010/5 "2022-03-11T13:19:33Z")

</div>

I face an error when I use stakeTokens function. error: Internal JSON-RPC error. { "code": -32000, "message": "execution reverted" }

I changed my code as below:

```auto
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract TokenFarm {
    IERC20 public daiToken;
    address owner;
    mapping(address => uint) public stakingBalance;

    /*
       Kovan DAI: 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa
    */
    constructor() {
        daiToken = IERC20(0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa);
        owner = msg.sender;
    }

    function stakeTokens(uint _amount) public {

        // amount should be > 0
        require(_amount > 0, "amount should be > 0");

        daiToken.approve(0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa, _amount);

        // transfer Dai to this contract for staking
        daiToken.transferFrom(msg.sender, address(this), _amount);
        
        // update staking balance
        stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;
    }

    // Unstaking Tokens (Withdraw)
    function unstakeTokens() public {
        uint balance = stakingBalance[msg.sender];

        // balance should be > 0
        require (balance > 0, "staking balance cannot be 0");

        // Transfer Mock Dai tokens to this contract for staking
        daiToken.transfer(msg.sender, balance);

        // reset staking balance to 0
        stakingBalance[msg.sender] = 0;
    }
}

```

---

<div class="post-metadata">

**Author:** ![maxareo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/maxareo/32/11606_2.png) [@maxareo](https://forum.openzeppelin.com/u/maxareo)\
**Post date:** [March 16, 2022, 12:44am UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010/6 "2022-03-16T00:44:34Z")

</div>

In this code, it is `this` contract approving `0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa`, but I think in your original logic, it should be the `msg.sender` approving `this` contract on USDC/DAI contract.

The approval by `msg.sender` on `this` contract happens on USDC/DAI contracts. They do not need to be written in `this` contract. It's a separate manual operation.

---

<div class="post-metadata">

**Author:** ![asato](https://avatars.discourse-cdn.com/v4/letter/a/dfb087/32.png) [@asato](https://forum.openzeppelin.com/u/asato)\
**Post date:** [March 16, 2022, 1:57am UTC](https://forum.openzeppelin.com/t/deposit-usdc-to-smart-contract/26010/7 "2022-03-16T01:57:04Z")

</div>

You need to approve dai for this contract to transfer it outside of contract before calling stakeTokens function.
