1

I have these functions and deployed my contract to Ropsten testnet.

  function setSmartContractAllownace(uint daiAmountIn) public {
     IERC20 daiToken = IERC20(ropstenDAI);
     daiToken.approve(address(this), daiAmountIn);
  }

  function getContractAddress() public view returns (address) {
      return address(this);
  }
  
  function getOwner() public view returns (address) {
      return msg.sender;
  }

When I call getContractAddress() and getOwner(), they return the correct values respectively.

However, when I call setSmartContractAllownace(1000), it successfully approves, but the caller (owner) is set to the address of the smart contract.

I verified this by going into DAI and checking the allowance.

This is when I put my account with DAI as _owner and smart contract as _spender

enter image description here

As you can see, this returns 0.

But if I put _owner also as smart contract,

enter image description here

it shows the correct allowance.

What is going on?

Thank you.

3
  • well approve allow you the spender to spend the amount of the transaction sender. So the owner is right because the contract send the transaction not you.
    – haxerl
    Commented Dec 12, 2020 at 11:48
  • How do you allow my contract to take Tokens from my account then? Commented Dec 12, 2020 at 13:01
  • 2
    Doing someToken.approve(address(this), someAmount) is meaningless, as you are only approving the contract to transfer tokens from itself (i.e., you can now call transferFrom inside this contract, but heck, you may as well just call transfer without any approval, and get the exact same result). Commented Dec 12, 2020 at 15:06

3 Answers 3

1

If you check the IERC20.approve() function's signature, you can see, that the first argument is the address that you allow to spend your DAI.

You used daiToken.approve(address(this), daiAmountIn) which means you allowed your contract to spend the DAI of your contract. This makes not much sense.

If you simply want to add some token to your contract from your own funds, you can transfer with your wallet to your contract's address. In this case just send some DAI to the contract's address.

If you would like to spend the caller's DAI tokens, then you have to allow it first. But of course the contract can't allow itself to spend others funds. You can go to etherscan to the DAI token's contract and call the approve() here with your contract's address. After that you will be able to call transferFrom() from your contract successfully up to the allowed amount.

3
  • My goal is to call daiToken.transferFrom(msg.sender, address(this), daiAmountIn) so I can transfer some tokens to my contract. If I call daiToken.approve(msg.sender, daiAmmountIn), it doesn't make sense to "transfer from msg.sender to contract", because I'm approved to do the opposite way. Commented Dec 12, 2020 at 13:04
  • my account in my wallet, which owns the contract Commented Dec 12, 2020 at 13:15
  • Editet my answer.
    – Wyctus
    Commented Dec 12, 2020 at 13:25
0

WARNING: DON'T EVER USE DELEGATECALL IN PRODUCTION. IT IS VERY DANGEROUS IF YOU DON'T KNOW HOW TO USE IT.

You need to use delegate call if you want the target contract to know that the caller is you.

DelegateCall, as the name implies, is calling mechanism of how caller contract calls target contract function but when target contract executed its logic, the context is not on the user who execute caller contract but on caller contract

In you case, it should be something like this: address(ropsten).delegatecall(abi.encodeWithSignature("approve(address,uint256)", address(this), value))

further reading: https://medium.com/coinmonks/delegatecall-calling-another-contract-function-in-solidity-b579f804178c

0

So, I had a misunderstanding about Tokens already publishes vs Token contract I was writing.

I ended up not using REMIX and my own smart contracts.

I used Web3js and loaded publishes DAI contract via this code

let token = new web3.eth.Contract(erc20ABI.abi, daiContractAddress)
token.methods.approve(uniswapRouter02Address, tokenAmountIn)
    .send({ from: web3.eth.defaultAccount, gas: gasLimit })
    ... // some listeners

Using the same approach, I was able to load other contracts I needed and use them.

The problems I didn't understand, or still don't know are

  1. I cannot approve tokens already published through REMIX
  2. If I call approve from a contract, the contract approves the fund to be used for the spender
  3. Those YouTube videos about writing contract for ERC20 tokens are MY OWN tokens, so I shouldn't do that if I'm not planning on publishing my own tokens.

Thank you for being patient and helping me out.

Your Answer

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

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