0

it might be simple but I am in the process of learning solidity. In remix IDE, debugging a contract function, the function starts with two requires:

 function transferFrom(address owner, address buyer, uint numTokens) public override returns (bool) {
    require(numTokens <= balances[owner]);    
    require(numTokens <= allowed[owner][msg.sender]);

    balances[owner] = balances[owner].sub(numTokens);
    allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
    balances[buyer] = balances[buyer].add(numTokens);
    emit Transfer(owner, buyer, numTokens);
    return true;
}

The balance of the owner is OK but the allowed mapping is empty.

The locals are:

{
    "owner": {
        "value": "0x5B38DA6A701C568545DCFCB03FCB875F56BEDDC4",
        "type": "address"
    },
    "buyer": {
        "value": "0xAB8483F64D9C6D1ECF9B849AE677DD3315835CB2",
        "type": "address"
    },
    "numTokens": {
        "value": "1",
        "type": "uint256"
    },
    "<1>": {
        "value": false,
        "type": "bool"
    }
}

The state are:

{
    "name": {
        "length": "0x0",
        "raw": "0x",
        "type": "string",
        "value": "<constant>",
        "constant": true,
        "immutable": false
    },
    "symbol": {
        "length": "0x0",
        "raw": "0x",
        "type": "string",
        "value": "<constant>",
        "constant": true,
        "immutable": false
    },
    "decimals": {
        "value": "<constant>",
        "type": "uint8",
        "constant": true,
        "immutable": false
    },
    "balances": {
        "value": {
            "0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4": {
                "value": "7770999963",
                "type": "uint256"
            },
            "000000000000000000000000ab8483f64d9c6d1ecf9b849ae677dd3315835cb2": {
                "value": "1",
                "type": "uint256"
            },
            "0000000000000000000000000000000000000000000000000000000000000000": {
                "value": "32",
                "type": "uint256"
            },
            "0000000000000000000000004b20993bc481177ec7e8f571cecae8a9e22c02db": {
                "value": "4",
                "type": "uint256"
            }
        },
        "type": "mapping(address => uint256)",
        "constant": false,
        "immutable": false
    },
    "allowed": {
        "value": {},
        "type": "mapping(address => mapping(address => uint256))",
        "constant": false,
        "immutable": false
    },
    "totalSupply_": {
        "value": "7771000000",
        "type": "uint256",
        "constant": false,
        "immutable": false
    },
    "addressTable": {
        "value": {},
        "type": "mapping(string => address)",
        "constant": false,
        "immutable": false
    }
}

How can the second require passes and the status in Remix IDE terminal is true Transaction mined and execution succeed?

6
  • What is the question? As per I understand the function should fail according to you but it is not failing, right? Also, please paste the contract code, I can check on my remix and see what's happening. May 22 at 9:11
  • @ZartajAfser you understood properly it should fail IMHO. The contract code I download as an example in my Remix project is etherscan.io/token/0xdacd69347de42babfaecd09dc88958378780fb62 and compiled it with the latest 0.6 version. May 22 at 9:46
  • How much token are you sending? May 22 at 11:41
  • 1 as shown by the locals I have pasted in the question @ZartajAfser May 22 at 11:52
  • 1
    Using hardhat console.log, I can log: console.log: allowed[owner][msg.sender] : 100 while still having an empty mapping: "allowed": { "value": {}, "type": "mapping(address => mapping(address => uint256))", "constant": false, "immutable": false } so I have to conclude you are right. But what a tricking debugging tool! Thank you @Ismael Jul 5 at 21:57

2 Answers 2

0

make sure before calling this function you approved the address you want to be able to spend your tokens, if you are using openZeppelin ERC20 contracts it has approve function which you can call if not create it your self and update the mapping with address and the amount of tokens you want to allow

1
0

I was able to figure it out thanks to @Ismael's comment.

Can you log allowed[owner][msg.sender]? It should be zero but if require didn't fail then perhaps it is some other value. I don't trust the visualization tools if the data is complicated they might fail.

The issue is coming from the tool RemixIDE, as confirmed by the log being different, see my comment.

By using hardhat console.log, I logged the value of allowed[owner][msg.sender] and it was 100, since this is more than the value I was providing to the function as numTokens, the require statement was passing.

Console logging values to ensure they match what you expect them to be is a powerful debugging method that can help you figure out why your code doesn't behave as you want it to.

Your Answer

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

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