Can't set the allowance to use transferFrom

Hi, here's my method to allow the user to sell "FRKC" ERC20 tokens to get ETH in return from my smart contract
When I log the allowance variable it stays at 0
On Remix I get the error: "Check the token allowance."
I made sure my user had enough tokens to sell and my contract has enough ETH to send
Am I supposed to call the approve function somewhere? Couldn't find a good example

function sell(uint256 amount) public {
        // Allowance
        uint256 allowance = FrkcReserve.allowance(msg.sender, address(this));
        require(allowance >= amount, "Check the token allowance.");

        // Get tokens from the user
        bool sent = FrkcReserve.transferFrom(msg.sender, address(this), amount);
        require(sent, "Failed to transfer tokens from user to vendor");

        // Sent ETH to the user
        (sent, ) = msg.sender.call{value: amountOfETHToTransfer}("");
        require(sent, "Failed to send ETH to the user");

        emit Sold(amount);
    }

Here are the steps I follow on Remix:

  1. Deploy my ERC20Basic token and my DEX contract
  2. DEX.buy > Buy ERC20Basic tokens in exchange of ETH (works fine)
  3. ERC20Basic.approve(contractAddress, tokenAmount) (works fine)
  4. ERC20Basic.allowance > Works fine, function returns the amount of the allowance

Problem comes when I try to sell tokens with this function:

function sell(uint256 amount) public {
        uint256 allowance = token.allowance(msg.sender, address(this));
        require(allowance >= amount, "Check the token allowance");
        
        token.transferFrom(msg.sender, address(this), amount);
        payable(msg.sender).transfer(amount);
        
        emit Sold(amount);
    }

I still get "Check the token allowance" When I log the allowance I get 0. When I log msg.sender and address(this) I get the same addresses I used on the Remix interface to get the value of the allowance manually So it feels like the allowance is reset to 0 for some reason when I call the sell function or that the sell function can't reach the value of the allowance

My allowance function inside of ERC20Basic contract:

function allowance(address owner, address delegate)
        public
        view
        override
        returns (uint256)
    {
        return allowed[owner][delegate];
    }

Approval function:

function approve(address delegate, uint256 numTokens)
        public
        override
        returns (bool)
    {
        allowed[msg.sender][delegate] = numTokens;
        emit Approval(msg.sender, delegate, numTokens);
        return true;
    }

Allowance structure:

mapping(address => mapping(address => uint256)) allowed;

Hi, your code looks like ok.
Before user call sell(), user should call FrkcReserve.approve(YOUR_CONTRACT, AMOUNT) ,and then call sell(), so is there a failed transaction? I can have a look to check more.

Yes here is the failed transaction:

transact to DEX.sell errored: VM error: revert. revert The transaction has been reverted to the initial state. Reason provided by the contract: "Check the token allowance". Debug the transaction to get more information.

[vm]

from: 0x5B3...eddC4

to: DEX.sell(uint256) 0xD7A...F771B

value: 0 wei

data: 0xe48...20000

logs: 0

hash: 0xfb7...e6075

Debug

|status|false Transaction mined but execution failed|
| --- | --- |
|transaction hash|0xfb706be73287202166bd3f219134897e19bd9b89e15ecc6306a2a81a89be6075|
|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
|to|DEX.sell(uint256) 0xD7ACd2a9FD159E69Bb102A1ca21C9a3e3A5F771B|
|gas|80000000 gas|
|transaction cost|38601 gas|
|execution cost|38601 gas|
|hash|0xfb706be73287202166bd3f219134897e19bd9b89e15ecc6306a2a81a89be6075|
|input|0xe48...20000|
|decoded input|{ "uint256 amount": "500000000000000000" }|
|decoded output|{}|
|logs|[]|
|val|0 wei|

I am calling approve through the remix interface and the allowance is set correctly when I check with the allowance method
But when I try to reach the allowance with the sell method it's equal to 0

Emmm, so you test on you local env or a test net? I want to check more about your transactions

I'n testing on Remix on Javascript VM

Here are the transactions:

[vm]

from: 0x5B3...eddC4

to: FaroukCoin.(constructor)

value: 0 wei

data: 0x608...b0033

logs: 1

hash: 0x7bb...29166

Debug

|status|true Transaction mined and execution succeed|
| --- | --- |
|transaction hash|0x7bbb2c8031552af98beaced2b23487a091d8858c3e9077002219c0f8eec29166|
|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
|to|FaroukCoin.(constructor)|
|gas|80000000 gas|
|transaction cost|1639656 gas|
|execution cost|1639656 gas|
|hash|0x7bbb2c8031552af98beaced2b23487a091d8858c3e9077002219c0f8eec29166|
|input|0x608...b0033|
|decoded input|{}|
|decoded output|-|
|logs|[ { "from": "0xd9145CCE52D386f254917e481eB44e9943F39138", "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "event": "Transfer", "args": { "0": "0x0000000000000000000000000000000000000000", "1": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "2": "10000000000000000000000", "from": "0x0000000000000000000000000000000000000000", "to": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "value": "10000000000000000000000" } } ]|
|val|0 wei|

creation of FaroukSwap pending...

[vm]

from: 0x5B3...eddC4

to: FaroukSwap.(constructor)

value: 0 wei

data: 0x608...b0033

logs: 1

hash: 0x86e...355b1

Debug

|status|true Transaction mined and execution succeed|
| --- | --- |
|transaction hash|0x86ef82754928a92c2e9a3e72e8c0bfb35faba316670710017d103fb50b4355b1|
|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
|to|FaroukSwap.(constructor)|
|gas|80000000 gas|
|transaction cost|2909926 gas|
|execution cost|2909926 gas|
|hash|0x86ef82754928a92c2e9a3e72e8c0bfb35faba316670710017d103fb50b4355b1|
|input|0x608...b0033|
|decoded input|{}|
|decoded output|-|
|logs|[ { "from": "0xB6A8ece75F656376c770cEF30d2F546558431ACD", "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "event": "Transfer", "args": { "0": "0x0000000000000000000000000000000000000000", "1": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "2": "10000000000000000000000", "from": "0x0000000000000000000000000000000000000000", "to": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "value": "10000000000000000000000" } } ]|
|val|0 wei|

transact to FaroukSwap.buy pending ...

[vm]

from: 0x5B3...eddC4

to: FaroukSwap.buy() 0xd8b...33fa8

value: 1000000000000000000 wei

data: 0xa6f...2ae3a

logs: 2

hash: 0xf51...c3a2c

Debug

|status|true Transaction mined and execution succeed|
| --- | --- |
|transaction hash|0xf513f01384ad5eaba88fc43d19da135a93b29197de99539644d949bea34c3a2c|
|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
|to|FaroukSwap.buy() 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8|
|gas|80000000 gas|
|transaction cost|62990 gas|
|execution cost|62990 gas|
|hash|0xf513f01384ad5eaba88fc43d19da135a93b29197de99539644d949bea34c3a2c|
|input|0xa6f...2ae3a|
|decoded input|{}|
|decoded output|{}|
|logs|[ { "from": "0xB6A8ece75F656376c770cEF30d2F546558431ACD", "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "event": "Transfer", "args": { "0": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "1": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "2": "100000000000000000000", "from": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "to": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "value": "100000000000000000000" } }, { "from": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "topic": "0x4e08ba899977cf7d4c2964bce71c6b9a7ef76ee5166a4c1249a1e08016e33ef1", "event": "Bought", "args": { "0": "100000000000000000000", "amount": "100000000000000000000" } } ]|
|val|1000000000000000000 wei|

call to FaroukSwap.getFrkcBalance

*CALL* [call]

from: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4

to: FaroukSwap.getFrkcBalance()

data: 0x2d7...f3859

Debug

|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
| --- | --- |
|to|FaroukSwap.getFrkcBalance() 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8|
|execution cost|29640 gas (Cost only applies when called by a contract)|
|hash|0x35c191a573dc18145b0d54cd1f35d20ed78e81c9c7602f9e58ade6782e03ecfe|
|input|0x2d7...f3859|
|decoded input|{}|
|decoded output|{ "0": "uint256: 9900000000000000000000" }|
|logs|[]|

call to FaroukSwap.getFrkcUserBalance

*CALL* [call]

from: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4

to: FaroukSwap.getFrkcUserBalance()

data: 0x9f4...a7393

Debug

|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
| --- | --- |
|to|FaroukSwap.getFrkcUserBalance() 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8|
|execution cost|29639 gas (Cost only applies when called by a contract)|
|hash|0x5e856e5bdaeb36170f078bdf5ddfc80841204f9d601bd6def65de7565c680212|
|input|0x9f4...a7393|
|decoded input|{}|
|decoded output|{ "0": "uint256: 100000000000000000000" }|
|logs|[]|

transact to FaroukCoin.approve pending ...

[vm]

from: 0x5B3...eddC4

to: FaroukCoin.approve(address,uint256) 0xd91...39138

value: 0 wei

data: 0x095...00000

logs: 1

hash: 0x00b...97d4d

Debug

|status|true Transaction mined and execution succeed|
| --- | --- |
|transaction hash|0x00b05a5799a2e811e9d8a247d2e75275740af11a44f078d2cad1603a4d397d4d|
|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
|to|FaroukCoin.approve(address,uint256) 0xd9145CCE52D386f254917e481eB44e9943F39138|
|gas|80000000 gas|
|transaction cost|46929 gas|
|execution cost|46929 gas|
|hash|0x00b05a5799a2e811e9d8a247d2e75275740af11a44f078d2cad1603a4d397d4d|
|input|0x095...00000|
|decoded input|{ "address spender": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "uint256 amount": "100000000000000000000" }|
|decoded output|{ "0": "bool: true" }|
|logs|[ { "from": "0xd9145CCE52D386f254917e481eB44e9943F39138", "topic": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", "event": "Approval", "args": { "0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "1": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "2": "100000000000000000000", "owner": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "spender": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8", "value": "100000000000000000000" } } ]|
|val|0 wei|

call to FaroukCoin.allowance

*CALL* [call]

from: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4

to: FaroukCoin.allowance(address,address)

data: 0xdd6...33fa8

Debug

|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
| --- | --- |
|to|FaroukCoin.allowance(address,address) 0xd9145CCE52D386f254917e481eB44e9943F39138|
|execution cost|25019 gas (Cost only applies when called by a contract)|
|hash|0x01a111e1de2975124829bd4c35930143bf7970a9f03b466480e6f0ab4bab8ad6|
|input|0xdd6...33fa8|
|decoded input|{ "address owner": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "address spender": "0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8" }|
|decoded output|{ "0": "uint256: 100000000000000000000" }|
|logs|[]|

transact to FaroukSwap.sell pending ...

**console.log:**  allowance: 0  msg.sender: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4  address(this): 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8

transact to FaroukSwap.sell errored: VM error: revert. revert The transaction has been reverted to the initial state. Reason provided by the contract: "Check the token allowance.". Debug the transaction to get more information.

[vm]

from: 0x5B3...eddC4

to: FaroukSwap.sell(uint256) 0xd8b...33fa8

value: 0 wei

data: 0xe48...80000

logs: 0

hash: 0xcf2...94012

Debug

|status|false Transaction mined but execution failed|
| --- | --- |
|transaction hash|0xcf2584b4257fe7082ee26fec3780f0e18003a4f66ce0383c0a593c8b04894012|
|from|0x5B38Da6a701c568545dCfcB03FcB875f56beddC4|
|to|FaroukSwap.sell(uint256) 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8|
|gas|80000000 gas|
|transaction cost|42503 gas|
|execution cost|42503 gas|
|hash|0xcf2584b4257fe7082ee26fec3780f0e18003a4f66ce0383c0a593c8b04894012|
|input|0xe48...80000|
|decoded input|{ "uint256 amount": "50000000000000000000" }|
|decoded output|{}|
|logs|[]|
|val|0 wei|

It seems like all action is right, you approved 100, and want to sell 50, so maybe you should check the token address in the function sell.