Owner address is changed once i run approve function from another smart contract

I have made a token on test network.

Now when I want to interect that token contract in my new smart contract there is problem which is not making any sense.

  1. first I am minting tokens in my wallet(account 1)

  2. then I am deploying new smart contract

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

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";


contract SampleContract {
    address public TKN = 0xc0FA1016cA91dFc66b7Ca4f147C79A15433cb6D8;  // this token is deployed on test-network you can see its balance and other things using ethscan
    // address public usdt = 0xdac17f958d2ee523a2206206994597c13d831ec7; // this is real world usdt token address
    

    function ApprovalFunds(address to, uint256 amount) public { // first you have to execute this function it will ask from the user 
    // that this amount of tokens will be set for allowence to owner(which is your address)
        ERC20(TKN).approve(to, amount);
    }
    // function TransferFunds(address to, uint256 amount) public { // secound this function will be executed which will transfer funds from current user
    // // to your account.
    //         ERC20(TKN).transfer(to, amount);
    // }

    function getBalance(address offf) public view returns(uint256) {
        return ERC20(TKN).balanceOf(offf);
    }

    function getAllowence(address owner, address spender) public view returns(uint256){
        return ERC20(TKN).allowance(owner, spender);
    }
    function TransferFromFun(address from, address to, uint256 amount) public {
        ERC20(TKN).transferFrom(from,to,amount);
    }
    
    function GetSupply() view public returns(uint256) {
        return ERC20(TKN).totalSupply();
    }

    function GetMyAddresss() view public returns(address) {
        return msg.sender;
    }


}
  1. Now in my wallet(account 1) I have minted tokens which i made at first place, I want to give approval of 1 OYEE(1*10**18) token to another wallet(account 2)
    image

  2. when I do so and check the logs it shows me that owner of token(which is allowing the approval of 1 OYEE to account 2) is the new smart contract that I have made not, It was supposed to be my address(account 1) not my contract. spender address is fine.

Hello @offfocs.1

Everything is working as intended.

When calling ApprovalFunds, your wallet is calling SampleContract ... and then SampleContract is calling approve on the token contract. From the point of view of the token, it is SampleContract that is calling approve, and so he is the owner that is setting an allowance.

Having a token allow an intermediary contract (such as SampleContract) to set the approval for someone else would be a critical security flaw. Millions have been lost that way (by tokens that used tx.origin instead of msg.sender).

Even if i am trying normal transfer function it is doing the same from addres is changed to that smart contract address(I want it to be current user address), then how am i supposed to make trasaction other than eth.

To have a contract C transfer users' tokens:

  • The user needs to call token.approve(C.address, amount) directly
  • The user then have to call C.something() which internally can call token.transferFrom(msg.sender, <destination of the token>, amount)

This is a very common pattern that is extensively documented on the web.

I am really sorry, I am not getting anything here,

  1. i made a token. i.e address: 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8
  2. I have a another smart contract where I will use that token
    IERC projectToken = IERC20(TokenAddress);
  3. now I want my smart contract to accept this erc20
  4. i want users to transfer 100 token to 0x838F9b8228a5C95a7c431bcDAb58E289f5D2A4DC this smart contract
  5. projectToken.approve(CurrentContractAddress, 100000000000000000000); now here is the thing I am not getting this line is allwoing msg.sender(which should be my account address since smart contract is calling projectToken so msg.sender is replaced with smart contract address(0x838F9b8228a5C95a7c431bcDAb58E289f5D2A4DC ) which is not making sense
  6. above line made things like this
    smart contract(0x838F9b8228a5C95a7c431bcDAb58E289f5D2A4DC ) allowed CurrentContractAddress(0x838F9b8228a5C95a7c431bcDAb58E289f5D2A4DC ) 100000000000000000000 tokens
  7. but I wanted it to be current account address allow CurrentContractAddress(0x838F9b8228a5C95a7c431bcDAb58E289f5D2A4DC ) 100000000000000000000 tokens

my account have 1000 OYEE tokens I want to send 10 OYEE tokens to 0x838F9b8228a5C95a7c431bcDAb58E289f5D2A4DC address how am i supposed to do that

Hi, welcome to the community! :wave:

Just like Amxx said above, the result matches your code correctly.
So if you do not want to get this result, and according to the 6, 7 you said above, maybe you should call token.approve(ContractAddress, 100000000000000000000) directly rather do this in a contract.

token.approve(ContractAddress, 100000000000000000000) yes but this thing is making this like this
msg.sender in approve function is same as contract address its like current contract is giving approval to itself

So your contract does not meet your requirements. As for how to do it, I am not sure.

Solved it sorry guys I was not making any sense I think,
to use transferFrom I have to call approve function from token samrt contract then I can call transferFrom function in my solidity contract xD.

1 Like

I am glad to hear that!

Hey Amxx,

I got your point. But then there will be a two way transaction for mint and approve. So instead of doing like this is there any other way of calling the approve() from my own contract address

Hi, welcome to the community! :wave:

If you do not want to use approve + transferFrom, maybe you can have a check at EIP2612